Repository: MannLabs/alphapept (language: python)

Issue:
Dev usability

Option to cancel a running job
**Is your feature request related to a problem? Please describe.**
If you realise that you selected inappropriate settings or similar, there should be a possibility to cancel a job. Also, in case alphapept gets stuck (as happend for me - see below) you should be able to cancel. 

**Describe the solution you'd like**
There could be a cancelation button in the 'queue' tab on the 'status' page. 

**Nice to have**
There could also be an option to prioritise jobs in the queue. In case an urgent analysis comes up you could move it up in the list. 

**Additional context**
Specifically, I have an issue with a job that (I guess) got stuck and it restarts and gets stuck at the same point again when I relaunch alphapept (this is stuck for >20 min already). I will write a separate issue for this.

<img width="1249" alt="Screenshot 2021-05-14 at 10 36 34" src="https://user-images.githubusercontent.com/20396322/118247113-16caf200-b4a3-11eb-9eed-e33b0cbc6021.png">




Discussion / hints:

Fix patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 8681aa5e..efee97b2 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.3.21
+current_version = 0.3.22
 commit = True
 tag = False
 parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+)(?P<build>\d+))?
diff --git a/README.md b/README.md
index f24bf230..445db3cf 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
 ![Windows Installer](https://github.com/MannLabs/alphapept/workflows/Windows%20Installer/badge.svg)
 
 # AlphaPept
-<img src="nbs\images\alphapept_logo.png">
+<img src="nbs/images/alphapept_logo.png" align="center">
 
  > A modular, python-based framework to analyze mass spectrometry data. Powered by nbdev. Supercharged with numba.
 
@@ -18,7 +18,7 @@
 The documentation is automatically built based on the jupyter notebooks (nbs/index.ipynb) and can be found [here](https://mannlabs.github.io/alphapept/):
 
 ## Windows Quickstart
-<img src="nbs\images\alphapept_screen.png" width="480," style="max-width: 480,px">
+<img src="nbs/images/alphapept_screen.png" width="480," align="center">
 
 1. Download the latest installer [here](https://github.com/MannLabs/alphapept/releases/latest), install and click the shortcut on the desktop. A browser window with the AlphaPept interface should open. In case Windows Firewall asks for network access for AlphaPept, please allow.
 2. In the `New Experiment` select a folder with raw files and FASTA files.
@@ -113,7 +113,7 @@ AlphaPept is meant to be a framework to implement and test new ideas quickly but
 
 For the [windows installation](https://github.com/MannLabs/alphapept/releases/latest), simply click on the shortcut after installation. The windows installation also installs the command-line tool so that you can call alphapept via `alphapept` in the command line.
 
-<img src="nbs\images\alphapept_cmd.png" width="480," style="max-width: 480,px">
+<img src="nbs/images/alphapept_cmd.png" width="480," align="center">
 
 ### Python Package
 
diff --git a/alphapept/__init__.py b/alphapept/__init__.py
index 443462b7..c3aa137e 100644
--- a/alphapept/__init__.py
+++ b/alphapept/__init__.py
@@ -1,1 +1,1 @@
-__version__ = "0.3.21"
+__version__ = "0.3.22"
diff --git a/alphapept/__version__.py b/alphapept/__version__.py
index a68ac4ee..0154f428 100644
--- a/alphapept/__version__.py
+++ b/alphapept/__version__.py
@@ -33,7 +33,7 @@
 AUTHOR_EMAIL = "straussmaximilian@gmail.com"
 COPYRIGHT = "Mann Labs"
 BRANCH = "master"
-VERSION_NO = "0.3.21"
+VERSION_NO = "0.3.22"
 MIN_PYTHON = "3.6"
 MAX_PYTHON = "4"
 AUDIENCE = "Developers"
diff --git a/alphapept/constants.py b/alphapept/constants.py
index 9ad3a002..a97feeda 100644
--- a/alphapept/constants.py
+++ b/alphapept/constants.py
@@ -12,60 +12,212 @@
 
 mass_dict = Dict.empty(key_type=types.unicode_type, value_type=types.float64)
 
-mass_dict["A"] = 71.03711379999999
+mass_dict["A"] = 71.0371138
 mass_dict["C"] = 103.0091845
-mass_dict["D"] = 115.02694309999998
-mass_dict["E"] = 129.04259309999998
+mass_dict["D"] = 115.0269431
+mass_dict["E"] = 129.0425931
 mass_dict["F"] = 147.0684139
 mass_dict["G"] = 57.02146373
 mass_dict["H"] = 137.0589119
-mass_dict["I"] = 113.08406399999998
-mass_dict["K"] = 128.09496299999998
-mass_dict["L"] = 113.08406399999998
-mass_dict["M"] = 131.04048459999998
-mass_dict["N"] = 114.04292749999999
+mass_dict["I"] = 113.084064
+mass_dict["K"] = 128.094963
+mass_dict["L"] = 113.084064
+mass_dict["M"] = 131.0404846
+mass_dict["N"] = 114.0429275
 mass_dict["P"] = 97.05276386
-mass_dict["Q"] = 128.05857749999998
+mass_dict["Q"] = 128.0585775
 mass_dict["R"] = 156.101111
 mass_dict["S"] = 87.03202843
 mass_dict["T"] = 101.0476785
 mass_dict["U"] = 150.9536333957
 mass_dict["V"] = 99.06841392
-mass_dict["W"] = 186.07931299999998
-mass_dict["Y"] = 163.06332859999998
+mass_dict["W"] = 186.079313
+mass_dict["Y"] = 163.0633286
 mass_dict["cC"] = 160.03064823
-mass_dict["oxM"] = 147.03539923
-mass_dict["aN"] = 156.05349219
-mass_dict["amN"] = 113.058911907
-mass_dict["aK"] = 170.10552768999997
+mass_dict["oxM"] = 147.03539923000002
+mass_dict["aA"] = 113.04767849000001
+mass_dict["aC"] = 145.01974919
+mass_dict["aD"] = 157.03750779
+mass_dict["aE"] = 171.05315779
+mass_dict["aF"] = 189.07897859
+mass_dict["aG"] = 99.03202842
+mass_dict["aH"] = 179.06947659
+mass_dict["aI"] = 155.09462869
+mass_dict["aK"] = 170.10552769
+mass_dict["aL"] = 155.09462869
+mass_dict["aM"] = 173.05104929
+mass_dict["aN"] = 156.05349219000001
+mass_dict["aP"] = 139.06332855
+mass_dict["aQ"] = 170.06914219
+mass_dict["aR"] = 198.11167569
+mass_dict["aS"] = 129.04259312
+mass_dict["aT"] = 143.05824319
+mass_dict["aU"] = 192.9641980857
+mass_dict["aV"] = 141.07897861
+mass_dict["aW"] = 228.08987769
+mass_dict["aY"] = 205.07389329
+mass_dict["amA"] = 70.053098207
+mass_dict["amC"] = 102.02516890700001
+mass_dict["amD"] = 114.042927507
+mass_dict["amE"] = 128.058577507
+mass_dict["amF"] = 146.084398307
+mass_dict["amG"] = 56.037448137
+mass_dict["amH"] = 136.074896307
+mass_dict["amI"] = 112.100048407
+mass_dict["amK"] = 127.11094740700001
+mass_dict["amL"] = 112.100048407
+mass_dict["amM"] = 130.056469007
+mass_dict["amN"] = 113.05891190700001
+mass_dict["amP"] = 96.068748267
+mass_dict["amQ"] = 127.07456190700002
+mass_dict["amR"] = 155.117095407
+mass_dict["amS"] = 86.048012837
+mass_dict["amT"] = 100.06366290700001
+mass_dict["amU"] = 149.9696178027
+mass_dict["amV"] = 98.084398327
+mass_dict["amW"] = 185.095297407
+mass_dict["amY"] = 162.079313007
 mass_dict["pS"] = 166.99835935
 mass_dict["pT"] = 181.01400942
 mass_dict["pY"] = 243.02965952
-mass_dict["deamN"] = 115.02694309299999
-mass_dict["deamNQ"] = 129.042593093
+mass_dict["deamN"] = 115.026943093
+mass_dict["deamNQ"] = 129.04259309300002
 mass_dict["cmC"] = 85.9826354
-mass_dict["pgE"] = 111.03202840999998
-mass_dict["pgQ"] = 111.03202839999999
-mass_dict["tmt0N"] = 338.1954054
+mass_dict["pgE"] = 111.03202841000001
+mass_dict["pgQ"] = 111.03202840000002
+mass_dict["tmt0A"] = 295.1895917
+mass_dict["tmt0C"] = 327.1616624
+mass_dict["tmt0D"] = 339.179421
+mass_dict["tmt0E"] = 353.195071
+mass_dict["tmt0F"] = 371.2208918
+mass_dict["tmt0G"] = 281.17394163
+mass_dict["tmt0H"] = 361.2113898
+mass_dict["tmt0I"] = 337.2365419
 mass_dict["tmt0K"] = 352.2474409
+mass_dict["tmt0L"] = 337.2365419
+mass_dict["tmt0M"] = 355.1929625
+mass_dict["tmt0N"] = 338.1954054
+mass_dict["tmt0P"] = 321.20524176000004
+mass_dict["tmt0Q"] = 352.2110554
+mass_dict["tmt0R"] = 380.2535889
+mass_dict["tmt0S"] = 311.18450633
+mass_dict["tmt0T"] = 325.2001564
+mass_dict["tmt0U"] = 375.1061112957
+mass_dict["tmt0V"] = 323.22089182
+mass_dict["tmt0W"] = 410.2317909
 mass_dict["tmt0Y"] = 387.2158065
-mass_dict["tmt2N"] = 339.1987603
+mass_dict["tmt2A"] = 296.1929466
+mass_dict["tmt2C"] = 328.16501730000004
+mass_dict["tmt2D"] = 340.1827759
+mass_dict["tmt2E"] = 354.1984259
+mass_dict["tmt2F"] = 372.2242467
+mass_dict["tmt2G"] = 282.17729653000004
+mass_dict["tmt2H"] = 362.2147447
+mass_dict["tmt2I"] = 338.2398968
 mass_dict["tmt2K"] = 353.2507958
-mass_dict["tmt2Y"] = 388.21916139999996
-mass_dict["tmt6N"] = 343.20585969999996
-mass_dict["tmt6K"] = 357.25789519999995
+mass_dict["tmt2L"] = 338.2398968
+mass_dict["tmt2M"] = 356.1963174
+mass_dict["tmt2N"] = 339.1987603
+mass_dict["tmt2P"] = 322.20859666
+mass_dict["tmt2Q"] = 353.21441030000005
+mass_dict["tmt2R"] = 381.25694380000004
+mass_dict["tmt2S"] = 312.18786123
+mass_dict["tmt2T"] = 326.2035113
+mass_dict["tmt2U"] = 376.1094661957
+mass_dict["tmt2V"] = 324.22424672
+mass_dict["tmt2W"] = 411.23514580000005
+mass_dict["tmt2Y"] = 388.2191614
+mass_dict["tmt6A"] = 300.200046
+mass_dict["tmt6C"] = 332.1721167
+mass_dict["tmt6D"] = 344.1898753
+mass_dict["tmt6E"] = 358.2055253
+mass_dict["tmt6F"] = 376.2313461
+mass_dict["tmt6G"] = 286.18439593
+mass_dict["tmt6H"] = 366.2218441
+mass_dict["tmt6I"] = 342.2469962
+mass_dict["tmt6K"] = 357.2578952
+mass_dict["tmt6L"] = 342.2469962
+mass_dict["tmt6M"] = 360.2034168
+mass_dict["tmt6N"] = 343.2058597
+mass_dict["tmt6P"] = 326.21569606
+mass_dict["tmt6Q"] = 357.2215097
+mass_dict["tmt6R"] = 385.2640432
+mass_dict["tmt6S"] = 316.19496062999997
+mass_dict["tmt6T"] = 330.2106107
+mass_dict["tmt6U"] = 380.11656559569997
+mass_dict["tmt6V"] = 328.23134612
+mass_dict["tmt6W"] = 415.2422452
 mass_dict["tmt6Y"] = 392.2262608
-mass_dict["itraq4KN"] = 258.14533789999996
-mass_dict["itraq4K"] = 272.19737339999995
-mass_dict["itraq4Y"] = 307.165739
+mass_dict["itraq4KA"] = 215.13952419999998
+mass_dict["itraq4KC"] = 247.1115949
+mass_dict["itraq4KD"] = 259.1293535
+mass_dict["itraq4KE"] = 273.14500350000003
+mass_dict["itraq4KF"] = 291.1708243
+mass_dict["itraq4KG"] = 201.12387413
+mass_dict["itraq4KH"] = 281.1613223
+mass_dict["itraq4KI"] = 257.1864744
+mass_dict["itraq4KK"] = 272.1973734
+mass_dict["itraq4KL"] = 257.1864744
+mass_dict["itraq4KM"] = 275.142895
+mass_dict["itraq4KN"] = 258.1453379
+mass_dict["itraq4KP"] = 241.15517426
+mass_dict["itraq4KQ"] = 272.1609879
+mass_dict["itraq4KR"] = 300.2035214
+mass_dict["itraq4KS"] = 231.13443883
+mass_dict["itraq4KT"] = 245.15008890000001
+mass_dict["itraq4KU"] = 295.0560437957
+mass_dict["itraq4KV"] = 243.17082432
+mass_dict["itraq4KW"] = 330.1817234
+mass_dict["itraq4KY"] = 307.16573900000003
+mass_dict["itraq4K"] = 272.1973734
+mass_dict["itraq4Y"] = 307.16573900000003
+mass_dict["itraq8KA"] = 375.2393133
+mass_dict["itraq8KC"] = 407.211384
+mass_dict["itraq8KD"] = 419.2291426
+mass_dict["itraq8KE"] = 433.2447926
+mass_dict["itraq8KF"] = 451.2706134
+mass_dict["itraq8KG"] = 361.22366323
+mass_dict["itraq8KH"] = 441.2611114
+mass_dict["itraq8KI"] = 417.2862635
+mass_dict["itraq8KK"] = 432.2971625
+mass_dict["itraq8KL"] = 417.2862635
+mass_dict["itraq8KM"] = 435.2426841
 mass_dict["itraq8KN"] = 418.245127
+mass_dict["itraq8KP"] = 401.25496336000003
+mass_dict["itraq8KQ"] = 432.260777
+mass_dict["itraq8KR"] = 460.3033105
+mass_dict["itraq8KS"] = 391.23422793
+mass_dict["itraq8KT"] = 405.249878
+mass_dict["itraq8KU"] = 455.1558328957
+mass_dict["itraq8KV"] = 403.27061342
+mass_dict["itraq8KW"] = 490.2815125
+mass_dict["itraq8KY"] = 467.2655281
 mass_dict["itraq8K"] = 432.2971625
 mass_dict["itraq8Y"] = 467.2655281
+mass_dict["eA"] = 337.1209813
+mass_dict["eC"] = 369.093052
+mass_dict["eD"] = 381.1108106
+mass_dict["eE"] = 395.1264606
+mass_dict["eF"] = 413.1522814
+mass_dict["eG"] = 323.10533123
+mass_dict["eH"] = 403.1427794
+mass_dict["eI"] = 379.1679315
 mass_dict["eK"] = 394.1788305
+mass_dict["eL"] = 379.1679315
+mass_dict["eM"] = 397.1243521
+mass_dict["eN"] = 380.126795
+mass_dict["eP"] = 363.13663136
+mass_dict["eQ"] = 394.142445
+mass_dict["eR"] = 422.1849785
+mass_dict["eS"] = 353.11589592999997
+mass_dict["eT"] = 367.131546
+mass_dict["eU"] = 417.03750089569996
+mass_dict["eV"] = 365.15228142
+mass_dict["eW"] = 452.1631805
+mass_dict["eY"] = 429.1471961
 mass_dict["arg10R"] = 166.10938057776002
 mass_dict["arg6R"] = 162.121241
-mass_dict["lys8K"] = 136.10916278887998
-
+mass_dict["lys8K"] = 136.10916278888
 mass_dict["Electron"] = 0.00054857990907
 mass_dict["Proton"] = 1.00727646687
 mass_dict["Hydrogen"] = 1.00782503223
@@ -73,8 +225,8 @@
 mass_dict["Oxygen"] = 15.994914619
 mass_dict["OH"] = 17.002739651229998
 mass_dict["H2O"] = 18.01056468346
-mass_dict["NH3"] = 17.03052
 
+mass_dict["NH3"] = 17.03052
 mass_dict["delta_M"] = 1.00286864
 mass_dict["delta_S"] = 0.0109135
 
@@ -104,6 +256,7 @@ def get_mass_dict(modfile="../modifications.tsv", aasfile="../amino_acids.tsv"):
     mods = pd.read_csv(modfile, delimiter="\t")
     aas = pd.read_csv(aasfile, delimiter="\t")
 
+
     mass_dict = Dict.empty(key_type=types.unicode_type, value_type=types.float64)
 
     for identifier, mass in aas[["Identifier", "Monoisotopic Mass (Da)"]].values:
@@ -116,8 +269,8 @@ def get_mass_dict(modfile="../modifications.tsv", aasfile="../amino_acids.tsv"):
 
         if ("<" in identifier) or (">" in identifier):
             for aa_identifier, aa_mass in aas[["Identifier", "Monoisotopic Mass (Da)"]].values:
-                if '^' in aa_identifier:
-                    new_identifier = identifier[:-1] + aa_identifier
+                if '^' in identifier:
+                    new_identifier = identifier[:-2] + aa_identifier
                     mass_dict[new_identifier] = float(mass) + mass_dict[aa_identifier]
                 elif aar == aa_identifier:
                     new_identifier = identifier[:-2] + aa_identifier
@@ -226,4 +379,6 @@ def __init__(self, m0, dm, intensities):
 protease_dict["trypsin_full"] = "([KR](?=[^P]))|((?<=W)K(?=P))|((?<=M)R(?=P))"
 protease_dict["trypsin_exception"] = "((?<=[CD])K(?=D))|((?<=C)K(?=[HY]))|((?<=C)R(?=K))|((?<=R)R(?=[HR]))"
 protease_dict["non-specific"] = "()"
-protease_dict["trypsin"] = "([KR](?=[^P]))"
\ No newline at end of file
+protease_dict["trypsin"] = "([KR](?=[^P]))"
+
+
diff --git a/alphapept/default_settings.yaml b/alphapept/default_settings.yaml
index 07425f67..1c33c86d 100644
--- a/alphapept/default_settings.yaml
+++ b/alphapept/default_settings.yaml
@@ -28,7 +28,8 @@ fasta:
   - oxM
   mods_variable_terminal: []
   mods_fixed_terminal_prot: []
-  mods_variable_terminal_prot: []
+  mods_variable_terminal_prot:
+  - a<^
   num_missed_cleavages: 2
   min_length: 6
   max_length: 27
diff --git a/alphapept/fasta.py b/alphapept/fasta.py
index c2898736..2621db83 100644
--- a/alphapept/fasta.py
+++ b/alphapept/fasta.py
@@ -333,6 +333,14 @@ def get_unique_peptides(peptides):
 def generate_peptides(peptide, **kwargs):
     """
     Wrapper to get modified peptides from a peptide
+
+    TODO:
+
+    There can be some edge-cases which are not defined yet.
+    Example:
+    Setting the same fixed modification - once for all peptides and once for only terminal for the protein.
+    The modification will thenbe applied twice.
+
     """
     mod_peptide = add_fixed_mods_terminal([peptide], kwargs['mods_fixed_terminal_prot'])
     mod_peptide = add_variable_mods_terminal(mod_peptide, kwargs['mods_variable_terminal_prot'])
@@ -346,6 +354,7 @@ def generate_peptides(peptide, **kwargs):
 
     all_peptides = []
     for peptide in peptides: #1 per, limit the number of isoforms
+
         #Regular peptides
         mod_peptides = add_fixed_mods([peptide], **kwargs)
         mod_peptides = add_fixed_mods_terminal(mod_peptides, **kwargs)
@@ -375,7 +384,7 @@ def generate_peptides(peptide, **kwargs):
 
 def check_peptide(peptide, AAs):
 
-    if set(peptide).issubset(AAs):
+    if set([_ for _ in peptide if _.isupper()]).issubset(AAs):
         return True
     else:
         return False
@@ -465,7 +474,10 @@ def get_spectra(peptides, mass_dict):
     spectra = List()
 
     for i in range(len(peptides)):
-        spectra.append(get_spectrum(peptides[i], mass_dict))
+        try:
+            spectra.append(get_spectrum(peptides[i], mass_dict))
+        except Exception: #TODO: This is to fix edge cases when having multiple modifications on the same AA.
+            pass
 
     return spectra
 
diff --git a/alphapept/gui/compare.py b/alphapept/gui/compare.py
new file mode 100644
index 00000000..15b6969c
--- /dev/null
+++ b/alphapept/gui/compare.py
@@ -0,0 +1,29 @@
+import streamlit as st
+
+
+def compare():
+    st.write('# Compare')
+    st.text('Compare the results of two different software.')
+
+
+    file_folder_1 = st.text_input("Enter path to file 1.", os.getcwd())
+    if not os.path.isdir(file_folder_1):
+        st.warning('Not a valid folder.')
+        file_folder_1 = None
+
+    file_folder_2 = st.text_input("Enter path to file 2.", os.getcwd())
+    if not os.path.isdir(file_folder_2):
+        st.warning('Not a valid folder.')
+        file_folder_2 = None
+
+    if file_folder_1 is not None and file_folder_2 is not None:
+
+        with st.spinner('Parsing Folder'):
+
+
+
+
+
+
+    #else:
+    #with st.spinner('Parsing folder'):
diff --git a/alphapept/gui/experiment.py b/alphapept/gui/experiment.py
index 90324b87..4bc1a597 100644
--- a/alphapept/gui/experiment.py
+++ b/alphapept/gui/experiment.py
@@ -2,9 +2,9 @@
 import os
 import pandas as pd
 import datetime
-from alphapept.paths import SETTINGS_TEMPLATE_PATH, QUEUE_PATH, DEFAULT_SETTINGS_PATH
+from alphapept.paths import SETTINGS_TEMPLATE_PATH, QUEUE_PATH, DEFAULT_SETTINGS_PATH, FASTA_PATH
 from alphapept.settings import load_settings_as_template, save_settings, load_settings
-from alphapept.gui.utils import escape_markdown
+from alphapept.gui.utils import escape_markdown, files_in_folder
 
 SETTINGS_TEMPLATE = load_settings(SETTINGS_TEMPLATE_PATH)
 
@@ -127,16 +127,9 @@ def experiment():
             recorder['experiment']['fasta_paths'] = [os.path.join(file_folder, _) for _ in fasta_files]
             recorder['experiment']['file_paths'] = [os.path.join(file_folder, _) for _ in raw_files]
 
-            if (len(raw_files) == 0) or (len(fasta_files) == 0):
-                if (len(raw_files) == 0) and (len(fasta_files) == 0):
-                    st.warning('No raw and FASTA files in folder.')
-                    refresh_folder()
-                elif len(raw_files) == 0:
-                    st.warning('No raw files in folder.')
-                    refresh_folder()
-                elif len(fasta_files) == 0:
-                    st.warning('No fasta files in folder.')
-                    refresh_folder()
+            if len(raw_files) == 0:
+                st.warning('No raw files in folder.')
+                refresh_folder()
 
             else:
                 with st.beta_expander(f"Raw files ({len(raw_files)})"):
@@ -145,6 +138,10 @@ def experiment():
                 if len(fasta_files) > 0:
                     with st.beta_expander(f"FASTA files ({len(fasta_files)})"):
                         st.table(pd.DataFrame(fasta_files, columns=['File']))
+                else:
+                    fasta_files_home_dir = files_in_folder(FASTA_PATH, '.fasta')
+                    selection = st.multiselect(f'Select FASTA files from {FASTA_PATH}', options=fasta_files_home_dir)
+                    recorder['experiment']['fasta_paths'] = [os.path.join(FASTA_PATH, _) for _ in selection]
 
                 #TODO: Include databse files
                 #if len(fasta_files) > 0:
diff --git a/alphapept/gui/fasta.py b/alphapept/gui/fasta.py
new file mode 100644
index 00000000..1f498444
--- /dev/null
+++ b/alphapept/gui/fasta.py
@@ -0,0 +1,42 @@
+import streamlit as st
+from alphapept.paths import FASTA_PATH
+from alphapept.gui.utils import files_in_folder_pandas
+import os
+import wget
+import datetime
+
+proteomes = {}
+proteomes['Homo_sapiens_UP000005640'] = 'UP000005640'
+proteomes['Escherichia_coli_UP000000625'] = 'UP000000625'
+proteomes['Saccharomyces_cerevisiae_UP000002311'] = 'UP000002311'
+
+def fasta():
+    st.write('# FASTA')
+
+    st.text(f'AlphaPept looks for FASTA files in {FASTA_PATH}.\nThese can be selected in the new experiment tab.\nYou can add own FASTA files to this folder.')
+
+    st.write('### Existing files')
+
+    fasta_files = files_in_folder_pandas(FASTA_PATH)
+
+    st.table(fasta_files)
+
+    st.write('### Download FASTA from Uniprot')
+
+    for p_ in proteomes:
+        if st.button(p_):
+
+            download_link = f'https://www.uniprot.org/uniprot/?query=proteome:{proteomes[p_]}%20reviewed:yes&format=fasta'
+            new_file = os.path.join(FASTA_PATH, datetime.datetime.today().strftime('%Y_%m_%d_')+p_+'.fasta')
+
+            st.code(f"Downloading {p_} to {new_file}.")
+
+            download_bar = st.progress(0)
+
+            def bar(current, total, width):
+                download_bar.progress(current/total)
+
+            with st.spinner('Downloading..'):
+                wget.download(download_link, new_file, bar = bar)
+
+            raise st.script_runner.RerunException(st.script_request_queue.RerunData(None))
diff --git a/alphapept/gui/history.py b/alphapept/gui/history.py
index 49fd6cb3..96422747 100644
--- a/alphapept/gui/history.py
+++ b/alphapept/gui/history.py
@@ -5,6 +5,7 @@
 import pandas as pd
 from alphapept.paths import PROCESSED_PATH, AP_PATH
 from alphapept.gui.utils import files_in_folder
+import numpy as np
 
 def load_files(file_list, callback = None):
     """
diff --git a/alphapept/gui/results.py b/alphapept/gui/results.py
index 4e7cd8c1..1ce26f42 100644
--- a/alphapept/gui/results.py
+++ b/alphapept/gui/results.py
@@ -7,7 +7,8 @@
 import alphapept.io
 import pandas as pd
 import base64
-
+import plotly.express as px
+from plotly.subplots import make_subplots
 
 def readable_files_from_yaml(results_yaml):
     """
@@ -74,6 +75,41 @@ def parse_file_and_display(file):
 
         make_df_downloadble(df, file)
 
+def plot_summary(results_yaml):
+    """
+    Plot summary
+    """
+
+    files = [os.path.splitext(_)[0] for _ in results_yaml['summary']['processed_files']]
+    data = [results_yaml['summary'][_] for _ in files]
+
+    data_df = pd.DataFrame(data)
+    data_df['filename'] = files
+
+    median_features = int(data_df['feature_table'].median())
+    median_protein_groups= int(data_df['protein_fdr_n_protein_group'].median())
+    median_peptides = int(data_df['protein_fdr_n_sequence'].median())
+
+    st.write(f"### Median: {median_features:,} features | {median_peptides:,} peptides | {median_protein_groups:,}  protein groups ")
+
+    col1, col2, col3 = st.beta_columns(3)
+
+    fig = make_subplots(rows=1, cols=3, subplot_titles=("Features", "Peptides", "Protein Groups", ))
+
+    hovertext = [data_df['filename'].values]
+
+    fig.add_bar(x=data_df.index, y=data_df['feature_table'], hovertext = hovertext, row=1, col=1, marker_color='#3dc5ef')
+    fig.add_bar(x=data_df.index, y=data_df['protein_fdr_n_protein_group'], hovertext = hovertext, row=1, col=2, marker_color='#42dee1')
+    fig.add_bar(x=data_df.index, y=data_df['protein_fdr_n_sequence'], hovertext = hovertext, row=1, col=3, marker_color='#6eecb9')
+
+    fig.update_layout(showlegend=False)
+    #fig.update_xaxes(tickmode = 'array', ticktext=list((range(len(data_df)))))
+
+    fig.update_layout(title_text="Run Summary")
+
+    st.write(fig)
+
+#42dee1
 
 def results():
     st.write("# Results")
@@ -88,26 +124,22 @@ def results():
 
     if selection == 'Previous results':
 
-        results_files = files_in_folder(PROCESSED_PATH, '.yaml')
-
-        with st.beta_expander(f"Total {len(results_files)} Files"):
-            st.table(results_files)
-
-        st.write('### Select results file')
-
-        selection = st.selectbox('Run', results_files)
+        results_files = files_in_folder(PROCESSED_PATH, '.yaml', sort='date')
+        selection = st.selectbox('Last run', results_files)
 
         if selection:
 
             filepath_selection = os.path.join(PROCESSED_PATH, selection)
             results_yaml = load_settings(filepath_selection)
 
+            plot_summary(results_yaml)
+
             with st.beta_expander("Run summary"):
                 st.write(results_yaml['summary'])
 
             read_log(os.path.splitext(filepath_selection)[0]+'.log')
             raw_files = readable_files_from_yaml(results_yaml)
-            st.write('### Select file from Experiment')
+            st.write('### Explore tables from experiment')
             file = st.selectbox('Select file from experiment', raw_files)
 
     elif selection == 'Enter file':
diff --git a/alphapept/gui/status.py b/alphapept/gui/status.py
index 4b1bb1e7..e2c7aa68 100644
--- a/alphapept/gui/status.py
+++ b/alphapept/gui/status.py
@@ -19,34 +19,40 @@ def queue_watcher():
 
     init_process(PROCESS_FILE)
 
-
     while True:
         queue_files = [_ for _ in os.listdir(QUEUE_PATH) if _.endswith('.yaml')]
         #print(f'{datetime.datetime.now()} queue_watcher running. {len(queue_files)} experiments to process.')
 
         if len(queue_files) > 0:
-            file_path = os.path.join(QUEUE_PATH, queue_files[0])
+
+            created = [time.ctime(os.path.getctime(os.path.join(QUEUE_PATH, _))) for _ in queue_files]
+            queue_df = pd.DataFrame(queue_files, columns = ['File'])
+            queue_df['Created'] = created
+
+            file_to_process = queue_df.sort_values('Created')['File'].iloc[0]
+
+            file_path = os.path.join(QUEUE_PATH, file_to_process)
             settings = load_settings_as_template(file_path)
 
             current_file = {}
             current_file['started'] = datetime.datetime.now()
-            current_file['file'] = queue_files[0]
+            current_file['file'] = file_to_process
 
             current_file_path = os.path.join(QUEUE_PATH, 'current_file')
 
             with open(current_file_path, "w") as file:
                 yaml.dump(current_file, file, sort_keys=False)
 
-            logfile = os.path.join(PROCESSED_PATH, os.path.splitext(queue_files[0])[0]+'.log')
+            logfile = os.path.join(PROCESSED_PATH, os.path.splitext(file_to_process)[0]+'.log')
             try:
                 settings_ = alphapept.interface.run_complete_workflow(settings, progress=True, logfile = logfile)
-                save_settings(settings_, os.path.join(PROCESSED_PATH, queue_files[0]))
+                save_settings(settings_, os.path.join(PROCESSED_PATH, file_to_process))
 
             except Exception as e:
                 print(f'Run {file_path} failed with {e}')
                 settings_ = settings.copy()
                 settings_['error'] = f"{e}"
-                save_settings(settings_, os.path.join(FAILED_PATH, queue_files[0]))
+                save_settings(settings_, os.path.join(FAILED_PATH, file_to_process))
 
             os.remove(file_path)
             if os.path.isfile(current_file_path):
@@ -54,10 +60,40 @@ def queue_watcher():
         else:
             time.sleep(15)
 
+def terminate_process():
+
+    with st.spinner('Terminating..'):
+
+        running, last_pid, p_name, status, queue_watcher_state = check_process(PROCESS_FILE)
+
+        p_ = psutil.Process(last_pid)
+        p_.terminate()
+        st.success(f'Terminated {last_pid}')
+
+        current_file = os.path.join(QUEUE_PATH, 'current_file')
+
+        with open(current_file, "r") as file:
+            cf_ = yaml.load(file, Loader=yaml.FullLoader)
+
+        cf = cf_['file']
+        file_in_process = os.path.join(QUEUE_PATH, cf)
+        target_file = os.path.join(FAILED_PATH, cf)
+
+        os.rename(file_in_process, target_file)
+        st.success(f'Moved {escape_markdown(file_in_process)} to {escape_markdown(target_file)}')
+
+        if os.path.isfile(current_file):
+            os.remove(current_file)
+        st.success(f'Cleaned up {escape_markdown(current_file)}')
+
+        time.sleep(3)
+
+        raise st.script_runner.RerunException(st.script_request_queue.RerunData(None))
+
 def status():
 
     st.write("# Status")
-    st.text(f'This page shows the status of the current analysis.\nSwitch to `New experiment` to define a new experiment')
+    st.text(f'This page shows the status of the current analysis.\nSwitch to `New experiment` to define a new experiment.\nSwitch to `Results` to see previous results.')
     status_msg = st.empty()
     failed_msg = st.empty()
 
@@ -109,6 +145,11 @@ def status():
 
         refresh = st.checkbox('Auto-Update Page')
 
+        if st.checkbox('Terminate process'):
+            st.error(f"This will abort the current run and move it to failed. Please confirm.")
+            if st.button('Confirm'):
+                terminate_process()
+
         while True:
             if os.path.isfile(current_file):
                 with open(current_file, "r") as file:
@@ -124,7 +165,7 @@ def status():
                     log_txt = []
                     f = open(logfile, "r")
 
-                lines = f.readlines()[-200:] # Limit to 200 lines 
+                lines = f.readlines()[-200:] # Limit to 200 lines
 
                 for line in lines:
                     if '__progress_current' in line:
diff --git a/alphapept/gui/utils.py b/alphapept/gui/utils.py
index 3869e257..193c6b57 100644
--- a/alphapept/gui/utils.py
+++ b/alphapept/gui/utils.py
@@ -5,6 +5,7 @@
 from multiprocessing import Process
 import psutil
 import time
+import pandas as pd
 
 def escape_markdown(text):
     """
@@ -15,16 +16,35 @@ def escape_markdown(text):
         text = text.replace(char, "\\"+char)
     return text
 
-def files_in_folder(folder, ending):
+def files_in_folder(folder, ending, sort='name'):
     """
-    Reads a folder and returns all files that have this ending. Sorts the files by name.
+    Reads a folder and returns all files that have this ending. Sorts the files by name or creation date.
     """
     files = [_ for _ in os.listdir(folder) if _.endswith(ending)]
-    files.sort()
+
+    if sort == 'name':
+        files.sort()
+    elif sort == 'date':
+        files.sort(key=lambda x: os.path.getctime(os.path.join(folder, x)))
+    else:
+        raise NotImplementedError
+
     files = files[::-1]
 
     return files
 
+def files_in_folder_pandas(folder):
+    """
+    Reads a folder and returns pandas dataframe
+    """
+    files = os.listdir(folder)
+    created = [time.ctime(os.path.getctime(os.path.join(folder, _))) for _ in files]
+    sizes = [os.path.getsize(os.path.join(folder, _))/1024**2 for _ in files]
+    df = pd.DataFrame(files, columns = ['File'])
+    df['Created'] = created
+    df['Filesize (Mb)'] = sizes
+
+    return df
 
 def read_log(log_path):
     """
diff --git a/alphapept/interface.py b/alphapept/interface.py
index 9e03a495..498b1765 100644
--- a/alphapept/interface.py
+++ b/alphapept/interface.py
@@ -637,7 +637,7 @@ def get_file_summary(ms_data):
                     df['rt_left'] = df['rt_apex'] - df['rt_start']
                     df['rt_tail'] = df['rt_right'] / df['rt_left']
 
-                for field in ['fwhm','int_sum','rt_length','o_mass_ppm_raw']:
+                for field in ['fwhm','int_sum','rt_length','rt_tail','o_mass_ppm_raw']:
                     if field in df.columns:
                         f_summary[key+'_median_'+field] = float(df[field].median())
 
diff --git a/alphapept/paths.py b/alphapept/paths.py
index d3e3392d..bff16f73 100644
--- a/alphapept/paths.py
+++ b/alphapept/paths.py
@@ -7,13 +7,15 @@
 SETTINGS_TEMPLATE_PATH = os.path.join(_this_directory, 'settings_template.yaml')
 
 HOME = os.path.expanduser("~")
-AP_PATH = os.path.join(HOME, "alphapept")
-QUEUE_PATH = os.path.join(HOME, "alphapept", "queue")
-PROCESSED_PATH = os.path.join(HOME, "alphapept", "finished")
-FAILED_PATH = os.path.join(HOME, "alphapept", "failed")
+AP_PATH = os.path.join(HOME, ".alphapept")
+QUEUE_PATH = os.path.join(HOME, ".alphapept", "queue")
+PROCESSED_PATH = os.path.join(HOME, ".alphapept", "finished")
+FAILED_PATH = os.path.join(HOME, ".alphapept", "failed")
+FASTA_PATH = os.path.join(HOME, ".alphapept", "fasta")
+
 PROCESS_FILE = os.path.join(QUEUE_PATH, 'process')
 FILE_WATCHER_FILE = os.path.join(QUEUE_PATH, 'file_watcher')
 
-for folder in [AP_PATH, QUEUE_PATH, PROCESSED_PATH, FAILED_PATH]:
+for folder in [AP_PATH, QUEUE_PATH, PROCESSED_PATH, FAILED_PATH, FASTA_PATH]:
     if not os.path.isdir(folder):
         os.mkdir(folder)
diff --git a/alphapept/settings_template.yaml b/alphapept/settings_template.yaml
index 01e8c53f..03170186 100644
--- a/alphapept/settings_template.yaml
+++ b/alphapept/settings_template.yaml
@@ -183,7 +183,8 @@ fasta:
     value:
       a<^: acetylation of protein N-terminus
       am>^: amidation of protein C-terminus
-    default: []
+    default:
+    - a<^
     description: Varibale terminal modifications on proteins.
   num_missed_cleavages:
     type: spinbox
diff --git a/alphapept/webui.py b/alphapept/webui.py
index ed115ef8..3b343a1b 100644
--- a/alphapept/webui.py
+++ b/alphapept/webui.py
@@ -1,5 +1,5 @@
 import streamlit as st
-from alphapept.gui import history, results, filewatcher, status, experiment
+from alphapept.gui import history, results, filewatcher, status, experiment, fasta#, compare
 from PIL import Image
 from alphapept.__version__ import VERSION_NO
 import os
@@ -28,15 +28,16 @@
 """
 st.markdown(hide_streamlit_style, unsafe_allow_html=True)
 
-
 st.sidebar.image(image, width = 300)
 st.sidebar.code(f"AlphaPept {VERSION_NO} \n{computer_name}")
 
 sidebar = {'Status': status.status,
            'New experiment': experiment.experiment,
+           'FASTA': fasta.fasta,
            'Results': results.results,
            'History': history.history,
            'FileWatcher': filewatcher.filewatcher}
+           #'Compare': compare.compare}
 
 menu = st.sidebar.radio("", list(sidebar.keys()))
 
diff --git a/docs/chem.html b/docs/chem.html
index b5311faf..28550675 100644
--- a/docs/chem.html
+++ b/docs/chem.html
@@ -8,14 +8,14 @@
 
 summary: "Chemistry related functions"
 description: "Chemistry related functions"
-nb_path: "nbs\01_chem.ipynb"
+nb_path: "nbs/01_chem.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\01_chem.ipynb
+# file to edit: nbs/01_chem.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -31,8 +31,8 @@
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>This notebook contains all chemistry-related functionality.  Here, a major part is functionality to generate isotope patterns and the averagine model. This is required for feature finding, where an isotope pattern is validated by being compared to its averagine model. We use the data structure <code>Isotopes</code> from constants to handle Isotopes. Next, we define the class <a href="/alphapept/chem.html#IsotopeDistribution"><code>IsotopeDistribution</code></a> to calculate isotope distributions for a given Isotope. The core of the calculation is the function <a href="/alphapept/chem.html#fast_add"><code>fast_add</code></a>, which allows the fast estimation of isotope distributions. <br>
-To calculate the isotope distribution for the averagine model, we define the function <a href="/alphapept/chem.html#get_average_formula"><code>get_average_formula</code></a>, which calculates the amino acid composition of the averagine molecule for the given mass.</p>
+<p>This notebook contains all chemistry-related functionality.  Here, a major part is functionality to generate isotope patterns and the averagine model. This is required for feature finding, where an isotope pattern is validated by being compared to its averagine model. We use the data structure <code>Isotopes</code> from constants to handle Isotopes. Next, we define the class <a href="/chem.html#IsotopeDistribution"><code>IsotopeDistribution</code></a> to calculate isotope distributions for a given Isotope. The core of the calculation is the function <a href="/chem.html#fast_add"><code>fast_add</code></a>, which allows the fast estimation of isotope distributions. <br>
+To calculate the isotope distribution for the averagine model, we define the function <a href="/chem.html#get_average_formula"><code>get_average_formula</code></a>, which calculates the amino acid composition of the averagine molecule for the given mass.</p>
 <p><em>Implementation note: Ideally, we would like to have constants such as isotopes as global variables to not overload functions with parameters. However, currently, numba is not able to handle typed dictionaries or jitclasses as globals. We, therefore, pass them as arguments.</em></p>
 
 </div>
@@ -59,7 +59,7 @@ <h2 id="IsotopeDistributions">IsotopeDistributions<a class="anchor-link" href="#
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h2 id="IsotopeDistribution" class="doc_header"><code>class</code> <code>IsotopeDistribution</code><a href="" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>IsotopeDistribution</code>(<strong>*<code>args</code></strong>, <strong>**<code>kwargs</code></strong>) :: <a href="/alphapept/chem.html#IsotopeDistribution"><code>IsotopeDistribution</code></a></p>
+<h2 id="IsotopeDistribution" class="doc_header"><code>class</code> <code>IsotopeDistribution</code><a href="" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>IsotopeDistribution</code>(<strong>*<code>args</code></strong>, <strong>**<code>kwargs</code></strong>) :: <a href="/chem.html#IsotopeDistribution"><code>IsotopeDistribution</code></a></p>
 </blockquote>
 <p>Class to calculate Isotope Distributions.</p>
 
@@ -234,7 +234,7 @@ <h4 id="dict_to_dist" class="doc_header"><code>dict_to_dist</code><a href="https
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Averagine">Averagine<a class="anchor-link" href="#Averagine"> </a></h2><p>The averagine model is based on <a href="https://www.sciencedirect.com/science/article/pii/1044030595000178">Senko et al.</a>. We define the function <a href="/alphapept/chem.html#get_average_formula"><code>get_average_formula</code></a> to calculate a dictionary with averagine masses.</p>
+<h2 id="Averagine">Averagine<a class="anchor-link" href="#Averagine"> </a></h2><p>The averagine model is based on <a href="https://www.sciencedirect.com/science/article/pii/1044030595000178">Senko et al.</a>. We define the function <a href="/chem.html#get_average_formula"><code>get_average_formula</code></a> to calculate a dictionary with averagine masses.</p>
 
 </div>
 </div>
@@ -306,7 +306,7 @@ <h4 id="get_average_formula" class="doc_header"><code>get_average_formula</code>
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>To directly calculate the isotope distribution of a molecule mass based on the averagine model, we define the wrapper function <a href="/alphapept/chem.html#mass_to_dist"><code>mass_to_dist</code></a>.</p>
+<p>To directly calculate the isotope distribution of a molecule mass based on the averagine model, we define the wrapper function <a href="/chem.html#mass_to_dist"><code>mass_to_dist</code></a>.</p>
 
 </div>
 </div>
@@ -442,7 +442,7 @@ <h4 id="mass_to_dist" class="doc_header"><code>mass_to_dist</code><a href="https
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Mass-Calculations">Mass Calculations<a class="anchor-link" href="#Mass-Calculations"> </a></h2><p><a href="/alphapept/chem.html#calculate_mass"><code>calculate_mass</code></a>: This function allows to calculate the precursor mass from the monoisotopic m/z and the charge.</p>
+<h2 id="Mass-Calculations">Mass Calculations<a class="anchor-link" href="#Mass-Calculations"> </a></h2><p><a href="/chem.html#calculate_mass"><code>calculate_mass</code></a>: This function allows to calculate the precursor mass from the monoisotopic m/z and the charge.</p>
 
 </div>
 </div>
diff --git a/docs/constants.html b/docs/constants.html
index f3cc90b0..72424a44 100644
--- a/docs/constants.html
+++ b/docs/constants.html
@@ -8,14 +8,14 @@
 
 summary: "Where all constats are stored"
 description: "Where all constats are stored"
-nb_path: "nbs\10_constants.ipynb"
+nb_path: "nbs/10_constants.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\10_constants.ipynb
+# file to edit: nbs/10_constants.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -70,7 +70,7 @@ <h2 id="Amino-Acids">Amino Acids<a class="anchor-link" href="#Amino-Acids"> </a>
 <div class="output_area">
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>{&#39;G&#39;, &#39;D&#39;, &#39;V&#39;, &#39;K&#39;, &#39;A&#39;, &#39;N&#39;, &#39;P&#39;, &#39;E&#39;, &#39;Q&#39;, &#39;T&#39;, &#39;C&#39;, &#39;M&#39;, &#39;H&#39;, &#39;I&#39;, &#39;W&#39;, &#39;R&#39;, &#39;F&#39;, &#39;U&#39;, &#39;Y&#39;, &#39;S&#39;, &#39;L&#39;}
+<pre>{&#39;P&#39;, &#39;I&#39;, &#39;A&#39;, &#39;L&#39;, &#39;M&#39;, &#39;N&#39;, &#39;F&#39;, &#39;D&#39;, &#39;G&#39;, &#39;S&#39;, &#39;Y&#39;, &#39;C&#39;, &#39;R&#39;, &#39;V&#39;, &#39;Q&#39;, &#39;U&#39;, &#39;T&#39;, &#39;H&#39;, &#39;K&#39;, &#39;W&#39;, &#39;E&#39;}
 </pre>
 </div>
 </div>
@@ -119,8 +119,8 @@ <h2 id="Mass-dict">Mass dict<a class="anchor-link" href="#Mass-dict"> </a></h2><
 <div class="output_area">
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>71.03711379999999
-128.09496299999998
+<pre>71.0371138
+128.094963
 </pre>
 </div>
 </div>
@@ -142,7 +142,7 @@ <h2 id="Mass-dict">Mass dict<a class="anchor-link" href="#Mass-dict"> </a></h2><
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_mass_dict" class="doc_header"><code>get_mass_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/constants.py#L84" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_mass_dict</code>(<strong><code>modfile</code></strong>=<em><code>'../modifications.tsv'</code></em>, <strong><code>aasfile</code></strong>=<em><code>'../amino_acids.tsv'</code></em>)</p>
+<h4 id="get_mass_dict" class="doc_header"><code>get_mass_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/constants.py#L236" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_mass_dict</code>(<strong><code>modfile</code></strong>=<em><code>'../modifications.tsv'</code></em>, <strong><code>aasfile</code></strong>=<em><code>'../amino_acids.tsv'</code></em>)</p>
 </blockquote>
 <p>Creates a mass_dict based on tsv files</p>
 <p>Args:
@@ -210,7 +210,7 @@ <h4 id="get_mass_dict" class="doc_header"><code>get_mass_dict</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Isotopes">Isotopes<a class="anchor-link" href="#Isotopes"> </a></h2><p>We define a <code>jitclass</code> that stores the base mass, the number of isotopes, and their abundances. We create the typed dictionary <a href="/alphapept/constants.html#isotopes"><code>isotopes</code></a> that stores different default isotopes.</p>
+<h2 id="Isotopes">Isotopes<a class="anchor-link" href="#Isotopes"> </a></h2><p>We define a <code>jitclass</code> that stores the base mass, the number of isotopes, and their abundances. We create the typed dictionary <a href="/constants.html#isotopes"><code>isotopes</code></a> that stores different default isotopes.</p>
 
 </div>
 </div>
@@ -226,7 +226,7 @@ <h2 id="Isotopes">Isotopes<a class="anchor-link" href="#Isotopes"> </a></h2><p>W
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h2 id="Isotope" class="doc_header"><code>class</code> <code>Isotope</code><a href="" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>Isotope</code>(<strong>*<code>args</code></strong>, <strong>**<code>kwargs</code></strong>) :: <a href="/alphapept/constants.html#Isotope"><code>Isotope</code></a></p>
+<h2 id="Isotope" class="doc_header"><code>class</code> <code>Isotope</code><a href="" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>Isotope</code>(<strong>*<code>args</code></strong>, <strong>**<code>kwargs</code></strong>) :: <a href="/constants.html#Isotope"><code>Isotope</code></a></p>
 </blockquote>
 
 </div>
diff --git a/docs/fasta.html b/docs/fasta.html
index e4a5bb96..38c809e0 100644
--- a/docs/fasta.html
+++ b/docs/fasta.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to generating spectra from FASTA files"
 description: "Functions related to generating spectra from FASTA files"
-nb_path: "nbs\03_fasta.ipynb"
+nb_path: "nbs/03_fasta.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\03_fasta.ipynb
+# file to edit: nbs/03_fasta.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -37,14 +37,14 @@
 <li>For each peptide, calculate a theoretical spectrum and precursor mass</li>
 <li>Save spectra</li>
 </ol>
-<p>Currently, <a href="/alphapept/speed.html#numba"><code>numba</code></a> has only limited string support. A lot of the functions are therefore Python-native.</p>
+<p>Currently, <a href="/speed.html#numba"><code>numba</code></a> has only limited string support. A lot of the functions are therefore Python-native.</p>
 
 </div>
 </div>
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Cleaving">Cleaving<a class="anchor-link" href="#Cleaving"> </a></h2><p>For cleaving, we use regular expressions to find potential cleavages sites and write the wrapper <a href="/alphapept/fasta.html#cleave_sequence"><code>cleave_sequence</code></a> to use it.</p>
+<h2 id="Cleaving">Cleaving<a class="anchor-link" href="#Cleaving"> </a></h2><p>For cleaving, we use regular expressions to find potential cleavages sites and write the wrapper <a href="/fasta.html#cleave_sequence"><code>cleave_sequence</code></a> to use it.</p>
 
 </div>
 </div>
@@ -245,7 +245,7 @@ <h4 id="count_internal_cleavages" class="doc_header"><code>count_internal_cleava
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Parsing">Parsing<a class="anchor-link" href="#Parsing"> </a></h2><p>Peptides are composed out of amino acids that are written in capital letters - <code>PEPTIDE</code>. to distinguish modifications, they are written in lowercase such as <code>PEPTIoxDE</code> and can be of arbitrary length. For a modified amino acid (AA), the modification precedes the letter of the amino acid. Decoys are indicated with an underscore. Therfore, the <a href="/alphapept/fasta.html#parse"><code>parse</code></a> function splits after <code>_</code>. When parsing, the peptide string is converted into a numba-compatible list, like so: <code>PEPoxTIDE</code> -&gt; <code>[P, E, P, oxT, I, D, E]</code>. This allows that we can use the <a href="/alphapept/constants.html#mass_dict"><code>mass_dict</code></a> from <code>alphapept.constants</code> to directly determine the masses for the corresponding amino acids.</p>
+<h2 id="Parsing">Parsing<a class="anchor-link" href="#Parsing"> </a></h2><p>Peptides are composed out of amino acids that are written in capital letters - <code>PEPTIDE</code>. to distinguish modifications, they are written in lowercase such as <code>PEPTIoxDE</code> and can be of arbitrary length. For a modified amino acid (AA), the modification precedes the letter of the amino acid. Decoys are indicated with an underscore. Therfore, the <a href="/fasta.html#parse"><code>parse</code></a> function splits after <code>_</code>. When parsing, the peptide string is converted into a numba-compatible list, like so: <code>PEPoxTIDE</code> -&gt; <code>[P, E, P, oxT, I, D, E]</code>. This allows that we can use the <a href="/constants.html#mass_dict"><code>mass_dict</code></a> from <code>alphapept.constants</code> to directly determine the masses for the corresponding amino acids.</p>
 
 </div>
 </div>
@@ -341,7 +341,7 @@ <h4 id="list_to_numba" class="doc_header"><code>list_to_numba</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Decoy">Decoy<a class="anchor-link" href="#Decoy"> </a></h2><p>The decoy strategy employed is a pseudo-reversal of the peptide sequence, keeping only the terminal amino-acid and reversing the rest. Additionally, we can call the functions <a href="/alphapept/fasta.html#swap_KR"><code>swap_KR</code></a> and and <a href="/alphapept/fasta.html#swap_AL"><code>swap_AL</code></a> that will swap the respective AAs. The function <a href="/alphapept/fasta.html#swap_KR"><code>swap_KR</code></a> will only swap terminal AAs. The swapping functions only work if the AA is not modified.</p>
+<h2 id="Decoy">Decoy<a class="anchor-link" href="#Decoy"> </a></h2><p>The decoy strategy employed is a pseudo-reversal of the peptide sequence, keeping only the terminal amino-acid and reversing the rest. Additionally, we can call the functions <a href="/fasta.html#swap_KR"><code>swap_KR</code></a> and and <a href="/fasta.html#swap_AL"><code>swap_AL</code></a> that will swap the respective AAs. The function <a href="/fasta.html#swap_KR"><code>swap_KR</code></a> will only swap terminal AAs. The swapping functions only work if the AA is not modified.</p>
 
 </div>
 </div>
@@ -646,6 +646,42 @@ <h4 id="add_fixed_mods" class="doc_header"><code>add_fixed_mods</code><a href="h
 </div>
 </div>
 
+</div>
+    {% endraw %}
+
+    {% raw %}
+    
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython3"><pre><span></span><span class="n">mods_fixed</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;aA&#39;</span><span class="p">,</span><span class="s1">&#39;cC&#39;</span><span class="p">,</span><span class="s1">&#39;bB&#39;</span><span class="p">]</span>
+<span class="n">peptide_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;cABCDEF&#39;</span><span class="p">]</span>
+
+<span class="n">add_fixed_mods</span><span class="p">(</span><span class="n">peptide_list</span><span class="p">,</span> <span class="n">mods_fixed</span><span class="p">)</span>
+</pre></div>
+
+    </div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+<div class="output_area">
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>[&#39;caAbBcCDEF&#39;]</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
     {% endraw %}
 
@@ -753,7 +789,7 @@ <h4 id="get_isoforms" class="doc_header"><code>get_isoforms</code><a href="https
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>Lastly, we define the wrapper <a href="/alphapept/fasta.html#add_variable_mods"><code>add_variable_mods</code></a> so that the functions can be called for lists of peptides and a list of variable modifications.</p>
+<p>Lastly, we define the wrapper <a href="/fasta.html#add_variable_mods"><code>add_variable_mods</code></a> so that the functions can be called for lists of peptides and a list of variable modifications.</p>
 
 </div>
 </div>
@@ -939,7 +975,7 @@ <h4 id="add_fixed_mods_terminal" class="doc_header"><code>add_fixed_mods_termina
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Terminal-Modifications---Variable">Terminal Modifications - Variable<a class="anchor-link" href="#Terminal-Modifications---Variable"> </a></h3><p>Lastly, to handle terminal variable modifications we use the function <a href="/alphapept/fasta.html#add_variable_mods_terminal"><code>add_variable_mods_terminal</code></a>. As the modifcation can only be at the terminal end this function only adds a peptide where the terminal end is modified.</p>
+<h3 id="Terminal-Modifications---Variable">Terminal Modifications - Variable<a class="anchor-link" href="#Terminal-Modifications---Variable"> </a></h3><p>Lastly, to handle terminal variable modifications we use the function <a href="/fasta.html#add_variable_mods_terminal"><code>add_variable_mods_terminal</code></a>. As the modifcation can only be at the terminal end this function only adds a peptide where the terminal end is modified.</p>
 
 </div>
 </div>
@@ -1036,7 +1072,7 @@ <h4 id="get_unique_peptides" class="doc_header"><code>get_unique_peptides</code>
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Generating-Peptides">Generating Peptides<a class="anchor-link" href="#Generating-Peptides"> </a></h3><p>Lastly we put all the functions into a wrapper <a href="/alphapept/fasta.html#generate_peptides"><code>generate_peptides</code></a>. It will accept a peptide and a dictionary with settings so that we can get all modified peptides</p>
+<h3 id="Generating-Peptides">Generating Peptides<a class="anchor-link" href="#Generating-Peptides"> </a></h3><p>Lastly we put all the functions into a wrapper <a href="/fasta.html#generate_peptides"><code>generate_peptides</code></a>. It will accept a peptide and a dictionary with settings so that we can get all modified peptides</p>
 
 </div>
 </div>
@@ -1055,6 +1091,11 @@ <h3 id="Generating-Peptides">Generating Peptides<a class="anchor-link" href="#Ge
 <h4 id="generate_peptides" class="doc_header"><code>generate_peptides</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L333" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_peptides</code>(<strong><code>peptide</code></strong>, <strong>**<code>kwargs</code></strong>)</p>
 </blockquote>
 <p>Wrapper to get modified peptides from a peptide</p>
+<p>TODO:</p>
+<p>There can be some edge-cases which are not defined yet.
+Example:
+Setting the same fixed modification - once for all peptides and once for only terminal for the protein.
+The modification will thenbe applied twice.</p>
 
 </div>
 
@@ -1077,7 +1118,7 @@ <h4 id="generate_peptides" class="doc_header"><code>generate_peptides</code><a h
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="check_peptide" class="doc_header"><code>check_peptide</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L376" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>check_peptide</code>(<strong><code>peptide</code></strong>, <strong><code>AAs</code></strong>)</p>
+<h4 id="check_peptide" class="doc_header"><code>check_peptide</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L385" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>check_peptide</code>(<strong><code>peptide</code></strong>, <strong><code>AAs</code></strong>)</p>
 </blockquote>
 
 </div>
@@ -1115,7 +1156,7 @@ <h4 id="check_peptide" class="doc_header"><code>check_peptide</code><a href="htt
 <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;mods_fixed&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;cC&quot;</span><span class="p">]</span>
 <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;mods_fixed_terminal&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
 <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;mods_fixed_terminal_prot&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
-<span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;mods_variable_terminal_prot&quot;</span><span class="p">]</span>  <span class="o">=</span> <span class="p">[]</span>
+<span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;mods_variable_terminal_prot&quot;</span><span class="p">]</span>  <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;a&lt;^&#39;</span><span class="p">]</span>
 <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;max_isoforms&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1024</span>
 <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;limit_modifications&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
 
@@ -1134,7 +1175,14 @@ <h4 id="check_peptide" class="doc_header"><code>check_peptide</code><a href="htt
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>[&#39;PEPTIDEM&#39;, &#39;PEPTIDEoxM&#39;, &#39;MEDITPEP_decoy&#39;, &#39;oxMEDITPEP_decoy&#39;]</pre>
+<pre>[&#39;PEPTIDEM&#39;,
+ &#39;PEPTIDEoxM&#39;,
+ &#39;MEDITPEP_decoy&#39;,
+ &#39;oxMEDITPEP_decoy&#39;,
+ &#39;aPEPTIDEM&#39;,
+ &#39;aPEPTIDEoxM&#39;,
+ &#39;MEDITPEaP_decoy&#39;,
+ &#39;oxMEDITPEaP_decoy&#39;]</pre>
 </div>
 
 </div>
@@ -1147,7 +1195,7 @@ <h4 id="check_peptide" class="doc_header"><code>check_peptide</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Mass-Calculations">Mass Calculations<a class="anchor-link" href="#Mass-Calculations"> </a></h2><p>Using the <a href="/alphapept/constants.html#mass_dict"><code>mass_dict</code></a> from <a href="/alphapept/constants.html"><code>constants</code></a> and being able to parse sequences with <a href="/alphapept/fasta.html#parse"><code>parse</code></a> one can simply look up the masses for each modified or unmodified amino acid and add everything up.</p>
+<h2 id="Mass-Calculations">Mass Calculations<a class="anchor-link" href="#Mass-Calculations"> </a></h2><p>Using the <a href="/constants.html#mass_dict"><code>mass_dict</code></a> from <a href="/constants.html"><code>constants</code></a> and being able to parse sequences with <a href="/fasta.html#parse"><code>parse</code></a> one can simply look up the masses for each modified or unmodified amino acid and add everything up.</p>
 
 </div>
 </div>
@@ -1170,7 +1218,7 @@ <h3 id="Precursor">Precursor<a class="anchor-link" href="#Precursor"> </a></h3><
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_precmass" class="doc_header"><code>get_precmass</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L388" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_precmass</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
+<h4 id="get_precmass" class="doc_header"><code>get_precmass</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L397" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_precmass</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
 </blockquote>
 <p>Calculate the mass of the neutral precursor</p>
 
@@ -1213,7 +1261,7 @@ <h4 id="get_precmass" class="doc_header"><code>get_precmass</code><a href="https
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>799.3599642034599</pre>
+<pre>799.35996420346</pre>
 </div>
 
 </div>
@@ -1226,9 +1274,9 @@ <h4 id="get_precmass" class="doc_header"><code>get_precmass</code><a href="https
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Fragments">Fragments<a class="anchor-link" href="#Fragments"> </a></h3><p>Likewise, we can calculate the masses of the fragment ions. We employ two functions: <a href="/alphapept/fasta.html#get_fragmass"><code>get_fragmass</code></a> and <a href="/alphapept/fasta.html#get_frag_dict"><code>get_frag_dict</code></a>.</p>
-<p><a href="/alphapept/fasta.html#get_fragmass"><code>get_fragmass</code></a> is a fast, <a href="/alphapept/speed.html#numba"><code>numba</code></a>-compatible function that calculates the fragmasses and returns an array indicating wheter the iontype was <code>b</code> or <code>y</code>.</p>
-<p><a href="/alphapept/fasta.html#get_frag_dict"><code>get_frag_dict</code></a> instead is not <a href="/alphapept/speed.html#numba"><code>numba</code></a>-compatible and hence a bit slower. It returns a dictionary with the respective ion and can be used for plotting theoretical spectra.</p>
+<h3 id="Fragments">Fragments<a class="anchor-link" href="#Fragments"> </a></h3><p>Likewise, we can calculate the masses of the fragment ions. We employ two functions: <a href="/fasta.html#get_fragmass"><code>get_fragmass</code></a> and <a href="/fasta.html#get_frag_dict"><code>get_frag_dict</code></a>.</p>
+<p><a href="/fasta.html#get_fragmass"><code>get_fragmass</code></a> is a fast, <a href="/speed.html#numba"><code>numba</code></a>-compatible function that calculates the fragmasses and returns an array indicating wheter the iontype was <code>b</code> or <code>y</code>.</p>
+<p><a href="/fasta.html#get_frag_dict"><code>get_frag_dict</code></a> instead is not <a href="/speed.html#numba"><code>numba</code></a>-compatible and hence a bit slower. It returns a dictionary with the respective ion and can be used for plotting theoretical spectra.</p>
 
 </div>
 </div>
@@ -1244,7 +1292,7 @@ <h3 id="Fragments">Fragments<a class="anchor-link" href="#Fragments"> </a></h3><
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_fragmass" class="doc_header"><code>get_fragmass</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L401" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_fragmass</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
+<h4 id="get_fragmass" class="doc_header"><code>get_fragmass</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L410" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_fragmass</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
 </blockquote>
 <p>Calculate the masses of the fragment ions</p>
 
@@ -1312,7 +1360,7 @@ <h4 id="get_fragmass" class="doc_header"><code>get_fragmass</code><a href="https
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_frag_dict" class="doc_header"><code>get_frag_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L432" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_frag_dict</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
+<h4 id="get_frag_dict" class="doc_header"><code>get_frag_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L441" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_frag_dict</code>(<strong><code>parsed_pep</code></strong>, <strong><code>mass_dict</code></strong>)</p>
 </blockquote>
 
 </div>
@@ -1355,17 +1403,17 @@ <h4 id="get_frag_dict" class="doc_header"><code>get_frag_dict</code><a href="htt
 
 <div class="output_text output_subarea output_execute_result">
 <pre>{&#39;b1&#39;: 98.06004032687,
- &#39;b2&#39;: 227.10263342686997,
+ &#39;b2&#39;: 227.10263342687,
  &#39;b3&#39;: 324.15539728686997,
  &#39;b4&#39;: 425.20307578687,
  &#39;b5&#39;: 538.28713978687,
  &#39;b6&#39;: 653.31408288687,
  &#39;y1&#39;: 148.06043425033,
  &#39;y2&#39;: 263.08737735033,
- &#39;y3&#39;: 376.1714413503299,
- &#39;y4&#39;: 477.21911985032995,
- &#39;y5&#39;: 574.2718837103299,
- &#39;y6&#39;: 703.3144768103299}</pre>
+ &#39;y3&#39;: 376.17144135033,
+ &#39;y4&#39;: 477.21911985033,
+ &#39;y5&#39;: 574.27188371033,
+ &#39;y6&#39;: 703.31447681033}</pre>
 </div>
 
 </div>
@@ -1439,14 +1487,14 @@ <h4 id="get_frag_dict" class="doc_header"><code>get_frag_dict</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Spectra">Spectra<a class="anchor-link" href="#Spectra"> </a></h3><p>The function <a href="/alphapept/fasta.html#get_spectrum"><code>get_spectrum</code></a> returns a tuple with the following content:</p>
+<h3 id="Spectra">Spectra<a class="anchor-link" href="#Spectra"> </a></h3><p>The function <a href="/fasta.html#get_spectrum"><code>get_spectrum</code></a> returns a tuple with the following content:</p>
 <ul>
 <li>precursor mass</li>
 <li>peptide sequence</li>
 <li>fragmasses</li>
 <li>fragtypes</li>
 </ul>
-<p>Likewise, <a href="/alphapept/fasta.html#get_spectra"><code>get_spectra</code></a> returns a list of tuples. We employ a list of tuples here as this way we can sort them easily by precursor mass.</p>
+<p>Likewise, <a href="/fasta.html#get_spectra"><code>get_spectra</code></a> returns a list of tuples. We employ a list of tuples here as this way we can sort them easily by precursor mass.</p>
 
 </div>
 </div>
@@ -1462,7 +1510,7 @@ <h3 id="Spectra">Spectra<a class="anchor-link" href="#Spectra"> </a></h3><p>The
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_spectrum" class="doc_header"><code>get_spectrum</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L450" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_spectrum</code>(<strong><code>peptide</code></strong>, <strong><code>mass_dict</code></strong>)</p>
+<h4 id="get_spectrum" class="doc_header"><code>get_spectrum</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L459" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_spectrum</code>(<strong><code>peptide</code></strong>, <strong><code>mass_dict</code></strong>)</p>
 </blockquote>
 
 </div>
@@ -1486,7 +1534,7 @@ <h4 id="get_spectrum" class="doc_header"><code>get_spectrum</code><a href="https
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="get_spectra" class="doc_header"><code>get_spectra</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L463" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_spectra</code>(<strong><code>peptides</code></strong>, <strong><code>mass_dict</code></strong>)</p>
+<h4 id="get_spectra" class="doc_header"><code>get_spectra</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L472" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>get_spectra</code>(<strong><code>peptides</code></strong>, <strong><code>mass_dict</code></strong>)</p>
 </blockquote>
 
 </div>
@@ -1526,7 +1574,7 @@ <h4 id="get_spectra" class="doc_header"><code>get_spectra</code><a href="https:/
 <div class="output_area">
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>[(799.3599642034599, &#39;PEPTIDE&#39;, array([ 98.06004033, 148.06043425, 227.10263343, 263.08737735,
+<pre>[(799.35996420346, &#39;PEPTIDE&#39;, array([ 98.06004033, 148.06043425, 227.10263343, 263.08737735,
        324.15539729, 376.17144135, 425.20307579, 477.21911985,
        538.28713979, 574.27188371, 653.31408289, 703.31447681]), array([ 1, -1,  2, -2,  3, -3,  4, -4,  5, -5,  6, -6], dtype=int8))]
 </pre>
@@ -1541,8 +1589,8 @@ <h4 id="get_spectra" class="doc_header"><code>get_spectra</code><a href="https:/
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Reading-FASTA">Reading FASTA<a class="anchor-link" href="#Reading-FASTA"> </a></h2><p>To read FASTA files we use the <code>SeqIO</code> module from the <code>Biopython</code> library. This is a generator expression so that we read one FASTA entry after another until the <code>StopIteration</code> is reached, which is implemented in <a href="/alphapept/fasta.html#read_fasta_file"><code>read_fasta_file</code></a>. Additionally, we define the funciton <a href="/alphapept/fasta.html#read_fasta_file_entries"><code>read_fasta_file_entries</code></a> that simply counts the number of FASTA entries.</p>
-<p>All FASTA entries that contain AAs which are not in the mass_dict can be checked with <a href="/alphapept/fasta.html#check_sequence"><code>check_sequence</code></a> and will be ignored.</p>
+<h2 id="Reading-FASTA">Reading FASTA<a class="anchor-link" href="#Reading-FASTA"> </a></h2><p>To read FASTA files we use the <code>SeqIO</code> module from the <code>Biopython</code> library. This is a generator expression so that we read one FASTA entry after another until the <code>StopIteration</code> is reached, which is implemented in <a href="/fasta.html#read_fasta_file"><code>read_fasta_file</code></a>. Additionally, we define the funciton <a href="/fasta.html#read_fasta_file_entries"><code>read_fasta_file_entries</code></a> that simply counts the number of FASTA entries.</p>
+<p>All FASTA entries that contain AAs which are not in the mass_dict can be checked with <a href="/fasta.html#check_sequence"><code>check_sequence</code></a> and will be ignored.</p>
 
 </div>
 </div>
@@ -1558,7 +1606,7 @@ <h2 id="Reading-FASTA">Reading FASTA<a class="anchor-link" href="#Reading-FASTA"
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="read_fasta_file" class="doc_header"><code>read_fasta_file</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L478" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_fasta_file</code>(<strong><code>fasta_filename</code></strong>=<em><code>''</code></em>)</p>
+<h4 id="read_fasta_file" class="doc_header"><code>read_fasta_file</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L490" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_fasta_file</code>(<strong><code>fasta_filename</code></strong>=<em><code>''</code></em>)</p>
 </blockquote>
 <p>Read a FASTA file line by line</p>
 
@@ -1583,7 +1631,7 @@ <h4 id="read_fasta_file" class="doc_header"><code>read_fasta_file</code><a href=
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="read_fasta_file_entries" class="doc_header"><code>read_fasta_file_entries</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L505" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_fasta_file_entries</code>(<strong><code>fasta_filename</code></strong>=<em><code>''</code></em>)</p>
+<h4 id="read_fasta_file_entries" class="doc_header"><code>read_fasta_file_entries</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L517" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_fasta_file_entries</code>(<strong><code>fasta_filename</code></strong>=<em><code>''</code></em>)</p>
 </blockquote>
 <p>Function to count entries in fasta file</p>
 
@@ -1608,7 +1656,7 @@ <h4 id="read_fasta_file_entries" class="doc_header"><code>read_fasta_file_entrie
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="check_sequence" class="doc_header"><code>check_sequence</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L522" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>check_sequence</code>(<strong><code>element</code></strong>, <strong><code>AAs</code></strong>, <strong><code>verbose</code></strong>=<em><code>False</code></em>)</p>
+<h4 id="check_sequence" class="doc_header"><code>check_sequence</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L534" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>check_sequence</code>(<strong><code>element</code></strong>, <strong><code>AAs</code></strong>, <strong><code>verbose</code></strong>=<em><code>False</code></em>)</p>
 </blockquote>
 <p>Checks wheter a sequence from a FASTA entry contains valid AAs</p>
 
@@ -1669,7 +1717,7 @@ <h4 id="check_sequence" class="doc_header"><code>check_sequence</code><a href="h
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Peptide-Dictionary">Peptide Dictionary<a class="anchor-link" href="#Peptide-Dictionary"> </a></h2><p>In order to efficiently store peptides, we rely on the Python dictionary. The idea is to have a dictionary with peptides as keys and indices to proteins as values. This way, one can quickly look up to which protein a peptide belongs to. The function <a href="/alphapept/fasta.html#add_to_pept_dict"><code>add_to_pept_dict</code></a> uses a regular python dictionary and allows to add peptides and stores indices to the originating proteins as a list. If a peptide is already present in the dictionary, the list is appended. The function returns a list of <code>added_peptides</code>, which were not present in the dictionary yet. One can use the function <a href="/alphapept/fasta.html#merge_pept_dicts"><code>merge_pept_dicts</code></a> to merge multiple peptide dicts.</p>
+<h2 id="Peptide-Dictionary">Peptide Dictionary<a class="anchor-link" href="#Peptide-Dictionary"> </a></h2><p>In order to efficiently store peptides, we rely on the Python dictionary. The idea is to have a dictionary with peptides as keys and indices to proteins as values. This way, one can quickly look up to which protein a peptide belongs to. The function <a href="/fasta.html#add_to_pept_dict"><code>add_to_pept_dict</code></a> uses a regular python dictionary and allows to add peptides and stores indices to the originating proteins as a list. If a peptide is already present in the dictionary, the list is appended. The function returns a list of <code>added_peptides</code>, which were not present in the dictionary yet. One can use the function <a href="/fasta.html#merge_pept_dicts"><code>merge_pept_dicts</code></a> to merge multiple peptide dicts.</p>
 
 </div>
 </div>
@@ -1685,7 +1733,7 @@ <h2 id="Peptide-Dictionary">Peptide Dictionary<a class="anchor-link" href="#Pept
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="add_to_pept_dict" class="doc_header"><code>add_to_pept_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L537" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>add_to_pept_dict</code>(<strong><code>pept_dict</code></strong>, <strong><code>new_peptides</code></strong>, <strong><code>i</code></strong>)</p>
+<h4 id="add_to_pept_dict" class="doc_header"><code>add_to_pept_dict</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L549" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>add_to_pept_dict</code>(<strong><code>pept_dict</code></strong>, <strong><code>new_peptides</code></strong>, <strong><code>i</code></strong>)</p>
 </blockquote>
 <p>Add peptides to the peptide dictionary</p>
 
@@ -1757,7 +1805,7 @@ <h4 id="add_to_pept_dict" class="doc_header"><code>add_to_pept_dict</code><a hre
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="merge_pept_dicts" class="doc_header"><code>merge_pept_dicts</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L553" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>merge_pept_dicts</code>(<strong><code>list_of_pept_dicts</code></strong>)</p>
+<h4 id="merge_pept_dicts" class="doc_header"><code>merge_pept_dicts</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L565" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>merge_pept_dicts</code>(<strong><code>list_of_pept_dicts</code></strong>)</p>
 </blockquote>
 
 </div>
@@ -1838,8 +1886,8 @@ <h4 id="merge_pept_dicts" class="doc_header"><code>merge_pept_dicts</code><a hre
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Generating-a-database">Generating a database<a class="anchor-link" href="#Generating-a-database"> </a></h2><p>To wrap everything up, we employ two functions <a href="/alphapept/fasta.html#generate_database"><code>generate_database</code></a> and <a href="/alphapept/fasta.html#generate_spectra"><code>generate_spectra</code></a>. The first one reads a FASTA file and generates a list of peptides, as well as the peptide dictionary and an ordered FASTA dictionary to be able to look up the protein indices laster. For the <code>callback</code> we first read the whole FASTA file to determine the total number of entries in the FASTA file.  For a typical FASTA file of 30 Mb with 40k entries, this should take less than a second. The progress of the digestion is monitored by processing the FASTA file one by one.
-The function <a href="/alphapept/fasta.html#generate_spectra"><code>generate_spectra</code></a> then calculates precursor masses and fragment ions. Here, we split the total_number of sequences in <code>1000</code> steps to be able to track progress with the <code>callback</code>.</p>
+<h2 id="Generating-a-database">Generating a database<a class="anchor-link" href="#Generating-a-database"> </a></h2><p>To wrap everything up, we employ two functions <a href="/fasta.html#generate_database"><code>generate_database</code></a> and <a href="/fasta.html#generate_spectra"><code>generate_spectra</code></a>. The first one reads a FASTA file and generates a list of peptides, as well as the peptide dictionary and an ordered FASTA dictionary to be able to look up the protein indices laster. For the <code>callback</code> we first read the whole FASTA file to determine the total number of entries in the FASTA file.  For a typical FASTA file of 30 Mb with 40k entries, this should take less than a second. The progress of the digestion is monitored by processing the FASTA file one by one.
+The function <a href="/fasta.html#generate_spectra"><code>generate_spectra</code></a> then calculates precursor masses and fragment ions. Here, we split the total_number of sequences in <code>1000</code> steps to be able to track progress with the <code>callback</code>.</p>
 
 </div>
 </div>
@@ -1855,7 +1903,7 @@ <h2 id="Generating-a-database">Generating a database<a class="anchor-link" href=
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="generate_fasta_list" class="doc_header"><code>generate_fasta_list</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L574" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_fasta_list</code>(<strong><code>fasta_paths</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>, <strong>**<code>kwargs</code></strong>)</p>
+<h4 id="generate_fasta_list" class="doc_header"><code>generate_fasta_list</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L586" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_fasta_list</code>(<strong><code>fasta_paths</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>, <strong>**<code>kwargs</code></strong>)</p>
 </blockquote>
 <p>Function to generate a database from a fasta file</p>
 
@@ -1880,7 +1928,7 @@ <h4 id="generate_fasta_list" class="doc_header"><code>generate_fasta_list</code>
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="generate_database" class="doc_header"><code>generate_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L606" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_database</code>(<strong><code>mass_dict</code></strong>, <strong><code>fasta_paths</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>, <strong>**<code>kwargs</code></strong>)</p>
+<h4 id="generate_database" class="doc_header"><code>generate_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L618" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_database</code>(<strong><code>mass_dict</code></strong>, <strong><code>fasta_paths</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>, <strong>**<code>kwargs</code></strong>)</p>
 </blockquote>
 <p>Function to generate a database from a fasta file</p>
 
@@ -1905,7 +1953,7 @@ <h4 id="generate_database" class="doc_header"><code>generate_database</code><a h
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="generate_spectra" class="doc_header"><code>generate_spectra</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L644" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_spectra</code>(<strong><code>to_add</code></strong>, <strong><code>mass_dict</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>)</p>
+<h4 id="generate_spectra" class="doc_header"><code>generate_spectra</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L656" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_spectra</code>(<strong><code>to_add</code></strong>, <strong><code>mass_dict</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>)</p>
 </blockquote>
 <p>Function to generate a database from a fasta file</p>
 
@@ -1928,7 +1976,7 @@ <h4 id="generate_spectra" class="doc_header"><code>generate_spectra</code><a hre
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Parallelized-version">Parallelized version<a class="anchor-link" href="#Parallelized-version"> </a></h2><p>To speed up spectra generated, one can use the parallelized version. The function <a href="/alphapept/fasta.html#generate_database_parallel"><code>generate_database_parallel</code></a> reads an entire FASTA file and splits it into multiple blocks. Each block will be processed, and the generated pept_dicts will be merged.</p>
+<h2 id="Parallelized-version">Parallelized version<a class="anchor-link" href="#Parallelized-version"> </a></h2><p>To speed up spectra generated, one can use the parallelized version. The function <a href="/fasta.html#generate_database_parallel"><code>generate_database_parallel</code></a> reads an entire FASTA file and splits it into multiple blocks. Each block will be processed, and the generated pept_dicts will be merged.</p>
 
 </div>
 </div>
@@ -1944,7 +1992,7 @@ <h2 id="Parallelized-version">Parallelized version<a class="anchor-link" href="#
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="block_idx" class="doc_header"><code>block_idx</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L673" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>block_idx</code>(<strong><code>len_list</code></strong>, <strong><code>block_size</code></strong>=<em><code>1000</code></em>)</p>
+<h4 id="block_idx" class="doc_header"><code>block_idx</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L685" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>block_idx</code>(<strong><code>len_list</code></strong>, <strong><code>block_size</code></strong>=<em><code>1000</code></em>)</p>
 </blockquote>
 <p>Create indices for a list of length len_list</p>
 
@@ -1969,7 +2017,7 @@ <h4 id="block_idx" class="doc_header"><code>block_idx</code><a href="https://git
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="blocks" class="doc_header"><code>blocks</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L688" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>blocks</code>(<strong><code>l</code></strong>, <strong><code>n</code></strong>)</p>
+<h4 id="blocks" class="doc_header"><code>blocks</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L700" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>blocks</code>(<strong><code>l</code></strong>, <strong><code>n</code></strong>)</p>
 </blockquote>
 <p>Create blocks from a given list</p>
 
@@ -1994,7 +2042,7 @@ <h4 id="blocks" class="doc_header"><code>blocks</code><a href="https://github.co
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="digest_fasta_block" class="doc_header"><code>digest_fasta_block</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L695" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>digest_fasta_block</code>(<strong><code>to_process</code></strong>)</p>
+<h4 id="digest_fasta_block" class="doc_header"><code>digest_fasta_block</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L707" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>digest_fasta_block</code>(<strong><code>to_process</code></strong>)</p>
 </blockquote>
 <p>Digest and create spectra for a whole fasta_block</p>
 
@@ -2019,7 +2067,7 @@ <h4 id="digest_fasta_block" class="doc_header"><code>digest_fasta_block</code><a
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="generate_database_parallel" class="doc_header"><code>generate_database_parallel</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L724" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_database_parallel</code>(<strong><code>settings</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>)</p>
+<h4 id="generate_database_parallel" class="doc_header"><code>generate_database_parallel</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L736" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>generate_database_parallel</code>(<strong><code>settings</code></strong>, <strong><code>callback</code></strong>=<em><code>None</code></em>)</p>
 </blockquote>
 <p>Function to generate a database from a fasta file</p>
 
@@ -2042,7 +2090,7 @@ <h4 id="generate_database_parallel" class="doc_header"><code>generate_database_p
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Parallel-search-on-large-files">Parallel search on large files<a class="anchor-link" href="#Parallel-search-on-large-files"> </a></h3><p>In some cases (e.g., a lot of modifications or very large FASTA files), it will not be useful to save the database as it will consume too much memory. Here, we use the function <a href="/alphapept/search.html#search_parallel"><code>search_parallel</code></a> from search. It creates theoretical spectra on the fly and directly searches against them. As we cannot create a pept_dict here, we need to create one from the search results. For this, we group peptides by their FASTA index and generate a lookup dictionary that can be used as a pept_dict.</p>
+<h3 id="Parallel-search-on-large-files">Parallel search on large files<a class="anchor-link" href="#Parallel-search-on-large-files"> </a></h3><p>In some cases (e.g., a lot of modifications or very large FASTA files), it will not be useful to save the database as it will consume too much memory. Here, we use the function <a href="/search.html#search_parallel"><code>search_parallel</code></a> from search. It creates theoretical spectra on the fly and directly searches against them. As we cannot create a pept_dict here, we need to create one from the search results. For this, we group peptides by their FASTA index and generate a lookup dictionary that can be used as a pept_dict.</p>
 <blockquote><p>Note that we are passing the settings argument here. Search results should be stored in the corresponding path in the hdf file.</p>
 </blockquote>
 
@@ -2060,7 +2108,7 @@ <h3 id="Parallel-search-on-large-files">Parallel search on large files<a class="
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="pept_dict_from_search" class="doc_header"><code>pept_dict_from_search</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L759" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>pept_dict_from_search</code>(<strong><code>settings</code></strong>)</p>
+<h4 id="pept_dict_from_search" class="doc_header"><code>pept_dict_from_search</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L771" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>pept_dict_from_search</code>(<strong><code>settings</code></strong>)</p>
 </blockquote>
 <p>Generates a peptide dict from a large search</p>
 
@@ -2111,7 +2159,7 @@ <h2 id="Saving">Saving<a class="anchor-link" href="#Saving"> </a></h2><p>To save
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="save_database" class="doc_header"><code>save_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L804" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>save_database</code>(<strong><code>spectra</code></strong>, <strong><code>pept_dict</code></strong>, <strong><code>fasta_dict</code></strong>, <strong><code>database_path</code></strong>, <strong>**<code>kwargs</code></strong>)</p>
+<h4 id="save_database" class="doc_header"><code>save_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L816" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>save_database</code>(<strong><code>spectra</code></strong>, <strong><code>pept_dict</code></strong>, <strong><code>fasta_dict</code></strong>, <strong><code>database_path</code></strong>, <strong>**<code>kwargs</code></strong>)</p>
 </blockquote>
 <p>Function to save a database to the *.hdf format.</p>
 
@@ -2143,7 +2191,7 @@ <h4 id="save_database" class="doc_header"><code>save_database</code><a href="htt
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h4 id="read_database" class="doc_header"><code>read_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L874" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_database</code>(<strong><code>database_path</code></strong>:<code>str</code>, <strong><code>array_name</code></strong>:<code>str</code>=<em><code>None</code></em>)</p>
+<h4 id="read_database" class="doc_header"><code>read_database</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/fasta.py#L886" class="source_link" style="float:right">[source]</a></h4><blockquote><p><code>read_database</code>(<strong><code>database_path</code></strong>:<code>str</code>, <strong><code>array_name</code></strong>:<code>str</code>=<em><code>None</code></em>)</p>
 </blockquote>
 
 </div>
diff --git a/docs/feature_finding.html b/docs/feature_finding.html
index ba2e40d2..4283c0ec 100644
--- a/docs/feature_finding.html
+++ b/docs/feature_finding.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to feature finding"
 description: "Functions related to feature finding"
-nb_path: "nbs\04_feature_finding.ipynb"
+nb_path: "nbs/04_feature_finding.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\04_feature_finding.ipynb
+# file to edit: nbs/04_feature_finding.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -267,7 +267,7 @@ <h4 id="convert_to_coord_path" class="doc_header"><code>convert_to_coord_path</c
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h4 id="Connecting-all-Centroids">Connecting all Centroids<a class="anchor-link" href="#Connecting-all-Centroids"> </a></h4><p>As we now have a function that can find pairs of centroids when given two lists of centroids, the next step is to write a function that connects all the centroids within a dataset. For this, we define the function <a href="/alphapept/feature_finding.html#connect_centroids"><code>connect_centroids</code></a>. Here, we use the <code>get_pairs_centroids</code> function to connect hills in consecutive scans <code>(n-&gt;n+1)</code> whenever their centroid m/z positions differ less than the defined threshold. If no matching peak is found in the next scan <code>(n+1)</code>, additional scans can be considered when looking in the scan after next <code>(n+2)</code>. The maximum distance between two hills can be set via the <code>gap</code> parameter.</p>
+<h4 id="Connecting-all-Centroids">Connecting all Centroids<a class="anchor-link" href="#Connecting-all-Centroids"> </a></h4><p>As we now have a function that can find pairs of centroids when given two lists of centroids, the next step is to write a function that connects all the centroids within a dataset. For this, we define the function <a href="/feature_finding.html#connect_centroids"><code>connect_centroids</code></a>. Here, we use the <code>get_pairs_centroids</code> function to connect hills in consecutive scans <code>(n-&gt;n+1)</code> whenever their centroid m/z positions differ less than the defined threshold. If no matching peak is found in the next scan <code>(n+1)</code>, additional scans can be considered when looking in the scan after next <code>(n+2)</code>. The maximum distance between two hills can be set via the <code>gap</code> parameter.</p>
 <p>For an efficient implementation to find all connected hills over all scans, we create a sparse matrix, named <code>results</code> that represent indices to all possible centroids. As the number of centroids varies for each scan, not all positions within the matrix represent a valid centroid. To distinguish these values, we fill the matrix with <code>-1</code> upon initialization. We can use the matrix to store the matching centroid as an integer that encodes its position. The x,y index for each cell represents the indices to the centroid list. The idea here is to have an efficient data structure to represent connections between centroids.</p>
 <p>To calculate indexes back and forth we define the functions <code>tup_to_ind</code> and <code>ind_to_tup</code>. This could in principle be also done with <code>numpy.unravel_index</code>, however, the numba implementation seems to be much faster.</p>
 <p>Additionally, we define a sparse matrix named <code>scores</code> that is intended to store the mass difference. If there are multiple possible connections between two centroids, only the best (i.e., shortest distance) will be stored.</p>
@@ -311,10 +311,10 @@ <h5 id="Foward-and-Backward-Search">Foward and Backward Search<a class="anchor-l
 <ul>
 <li>c-&gt; d</li>
 </ul>
-<p><img src="/alphapept/images/undirected.png" alt="undirected"></p>
+<p><img src="/images/undirected.png" alt="undirected"></p>
 <p>The resulting hill would have a branch to the c centroid, which is obviously intended. To circumvent this, we additionally perform the search backwards. (Note the functions <code>connect_centroids_forward</code> and <code>connect_centroids_backward</code>).  Now, as we only store, the best connection between two centroids  <code>d</code> will only be connected to <code>b</code>. To, therefore, remove branches, we remove all connections that are not double.</p>
-<p><img src="/alphapept/images/directed.png" alt="directed"></p>
-<p>We define a wrapper function named <a href="/alphapept/feature_finding.html#connect_centroids"><code>connect_centroids</code></a> that allows to search with a gaps ize and returns lists of indices of the connected centroids.</p>
+<p><img src="/images/directed.png" alt="directed"></p>
+<p>We define a wrapper function named <a href="/feature_finding.html#connect_centroids"><code>connect_centroids</code></a> that allows to search with a gaps ize and returns lists of indices of the connected centroids.</p>
 
 </div>
 </div>
@@ -322,7 +322,7 @@ <h5 id="Foward-and-Backward-Search">Foward and Backward Search<a class="anchor-l
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
 <h3 id="Connecting-hills">Connecting hills<a class="anchor-link" href="#Connecting-hills"> </a></h3><p>Having all the connected centroids, we would like to find <code>hills</code>, referring to centroids that are connected. We can achieve this by creating a graph <code>G</code> with the <code>networkx</code>-package. Here, each connection is added as an edge using the <code>add_edge</code> method to the graph. We can then use the <code>connected_components</code> function to extract all the connected components.</p>
-<p><code>NetworkX</code> is known to be memory <a href="https://groups.google.com/forum/#!topic/networkx-discuss/Etd4GpkjPdA">consuming</a> and can take hundreds of bytes per edge. For millions of connections, we will, therefore, consume Gigabytes of memory. To keep the graph small, we continuously feed the graph until we reach a certain scan number <code>buffer size</code>. Once the limit is reached, we extract all completed hills and remove all nodes that are part of a completed hill or cannot be connected anymore. Once all edges are added, we perform a final extraction step. Finally, everything is put into the <a href="/alphapept/feature_finding.html#get_hills"><code>get_hills</code></a> function.</p>
+<p><code>NetworkX</code> is known to be memory <a href="https://groups.google.com/forum/#!topic/networkx-discuss/Etd4GpkjPdA">consuming</a> and can take hundreds of bytes per edge. For millions of connections, we will, therefore, consume Gigabytes of memory. To keep the graph small, we continuously feed the graph until we reach a certain scan number <code>buffer size</code>. Once the limit is reached, we extract all completed hills and remove all nodes that are part of a completed hill or cannot be connected anymore. Once all edges are added, we perform a final extraction step. Finally, everything is put into the <a href="/feature_finding.html#get_hills"><code>get_hills</code></a> function.</p>
 <h4 id="Parallelization-Strategies">Parallelization Strategies<a class="anchor-link" href="#Parallelization-Strategies"> </a></h4><p>Currently, the parallel connection of hills is not implemented yet. A possible way could be to process individual chunks of edges in parallel and then combine them together, as it is done in <code>Dinosaur</code>.</p>
 
 </div>
@@ -616,7 +616,7 @@ <h2 id="Calculating-Hill-Statistics">Calculating Hill Statistics<a class="anchor
 <p>{% raw %}
 $$\Delta \overline{m} = \sqrt{\frac{\sum_{b=1}^{B}(\overline{m}_b - \overline{m} )}{(B-1)}}$$
 {% endraw %}</p>
-<p>The calculation of hill statistics for a single hill is implemented in <code>get_hill_stats</code>. To calculate the hill stats for a list of hills, we can call the wrapper <a href="/alphapept/feature_finding.html#get_hill_data"><code>get_hill_data</code></a>.</p>
+<p>The calculation of hill statistics for a single hill is implemented in <code>get_hill_stats</code>. To calculate the hill stats for a list of hills, we can call the wrapper <a href="/feature_finding.html#get_hill_data"><code>get_hill_data</code></a>.</p>
 
 </div>
 </div>
@@ -678,7 +678,7 @@ <h4 id="get_hill_data" class="doc_header"><code>get_hill_data</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Combining-Hills-to-Isotope-Patterns">Combining Hills to Isotope Patterns<a class="anchor-link" href="#Combining-Hills-to-Isotope-Patterns"> </a></h2><p>After obtaining summary statistics of hills, the next step is to check whether they belong together to form an isotope pattern. For this, we check wheter it is possible that they are neighbors in an isotope pattern, e.g. one having a 12C atom that has been replaced by a 13C version. The detailed criterion for the check is implemented in <a href="/alphapept/feature_finding.html#check_isotope_pattern"><code>check_isotope_pattern</code></a> and is as follows:</p>
+<h2 id="Combining-Hills-to-Isotope-Patterns">Combining Hills to Isotope Patterns<a class="anchor-link" href="#Combining-Hills-to-Isotope-Patterns"> </a></h2><p>After obtaining summary statistics of hills, the next step is to check whether they belong together to form an isotope pattern. For this, we check wheter it is possible that they are neighbors in an isotope pattern, e.g. one having a 12C atom that has been replaced by a 13C version. The detailed criterion for the check is implemented in <a href="/feature_finding.html#check_isotope_pattern"><code>check_isotope_pattern</code></a> and is as follows:</p>
 <p>{% raw %}
 $$\left | \Delta m-\frac{\Delta M}{z} \right |\leq \sqrt{\left ( \frac{\Delta S}{z}  \right )^{2}+\Delta {m_{1}}^{2} +\Delta {m_{2}}^{2}}$$
 {% endraw %}</p>
@@ -811,7 +811,7 @@ <h4 id="correlate" class="doc_header"><code>correlate</code><a href="https://git
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Extracting-pre-Isotope-Patterns">Extracting pre-Isotope Patterns<a class="anchor-link" href="#Extracting-pre-Isotope-Patterns"> </a></h3><p>Now having two criteria to check whether hills could, in principle, belong together, we define the wrapper functions <a href="/alphapept/feature_finding.html#extract_edge"><code>extract_edge</code></a> and <code>get_edges</code> to extract the connected hills. To minimize the number of comparisons we need to perform, we only compare the hills that overlap in time (i.e., the start of one hill <code>rt_min</code> needs to be before the end of the other hill <code>rt_max</code>) and are less than the sum of $\Delta M$ and $\Delta S$ apart.</p>
+<h3 id="Extracting-pre-Isotope-Patterns">Extracting pre-Isotope Patterns<a class="anchor-link" href="#Extracting-pre-Isotope-Patterns"> </a></h3><p>Now having two criteria to check whether hills could, in principle, belong together, we define the wrapper functions <a href="/feature_finding.html#extract_edge"><code>extract_edge</code></a> and <code>get_edges</code> to extract the connected hills. To minimize the number of comparisons we need to perform, we only compare the hills that overlap in time (i.e., the start of one hill <code>rt_min</code> needs to be before the end of the other hill <code>rt_max</code>) and are less than the sum of $\Delta M$ and $\Delta S$ apart.</p>
 <p>To extract all hills that belong together, we again rely on the <code>NetworkX</code>-package to extract the connected components.</p>
 
 </div>
@@ -906,12 +906,12 @@ <h4 id="get_pre_isotope_patterns" class="doc_header"><code>get_pre_isotope_patte
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
 <h3 id="Extracting-Isotope-Patterns">Extracting Isotope Patterns<a class="anchor-link" href="#Extracting-Isotope-Patterns"> </a></h3><p>The extracted pre-isotope patterns may not be consistent because their pair-wise mass differences may not correspond to the same charge. To extract isotope patterns from pre-isotope patterns, we need to ensure that they are consistent for a single charge.</p>
-<p>To do this, we start with the 100 most intense peaks from a pre-isotope pattern to be used as a seed. For each seed and charge we then try to extract the longest consistent isotope pattern. To check wheter a hill is consistent with the seed we employ a modified checking criterion (<a href="/alphapept/feature_finding.html#check_isotope_pattern_directed"><code>check_isotope_pattern_directed</code></a>) to be as follows:</p>
+<p>To do this, we start with the 100 most intense peaks from a pre-isotope pattern to be used as a seed. For each seed and charge we then try to extract the longest consistent isotope pattern. To check wheter a hill is consistent with the seed we employ a modified checking criterion (<a href="/feature_finding.html#check_isotope_pattern_directed"><code>check_isotope_pattern_directed</code></a>) to be as follows:</p>
 <p>{% raw %}
 $$\left | m-m_j-\frac{j\Delta M}{z} \right |\leq \sqrt{\left ( \frac{\Delta S}{z}  \right )^{2}+\Delta {m}^{2} +\Delta {m_{j}}^{2}}$$
 {% endraw %}</p>
 <p>Here $m$ is the mass of a seed peak, and $m_{j}$ refers to a peak relative to the seed. $j$ refers to the peaks to the left or right (negative or positive index) within the pattern. $j$ needs to run over consecutive values so that gaps are not allowed. Besides this consistency check, two hills are also checked to have a cosine correlation of at least 0.6.</p>
-<p>Programmatically, this is implemented in <a href="/alphapept/feature_finding.html#grow_trail"><code>grow_trail</code></a> and <a href="/alphapept/feature_finding.html#grow"><code>grow</code></a>. These function uses a recursive approach that adds matching hills to the seed on the left and right side until no more hills can be added.</p>
+<p>Programmatically, this is implemented in <a href="/feature_finding.html#grow_trail"><code>grow_trail</code></a> and <a href="/feature_finding.html#grow"><code>grow</code></a>. These function uses a recursive approach that adds matching hills to the seed on the left and right side until no more hills can be added.</p>
 
 </div>
 </div>
@@ -1164,10 +1164,10 @@ <h4 id="truncate" class="doc_header"><code>truncate</code><a href="https://githu
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Isolating-Isotope_patterns">Isolating Isotope_patterns<a class="anchor-link" href="#Isolating-Isotope_patterns"> </a></h2><p>The extraction of the longest consistent isotope pattern is implemented in <a href="/alphapept/feature_finding.html#isolate_isotope_pattern"><code>isolate_isotope_pattern</code></a>. Here, three additional checks for an isotope pattern are implemented.</p>
-<p>The first one is <a href="/alphapept/feature_finding.html#truncate"><code>truncate</code></a>. Here, one checks the seed position, whether it has a minimum to its left or right side. If a minimum is found, the isotope pattern is cut off at this position.</p>
+<h2 id="Isolating-Isotope_patterns">Isolating Isotope_patterns<a class="anchor-link" href="#Isolating-Isotope_patterns"> </a></h2><p>The extraction of the longest consistent isotope pattern is implemented in <a href="/feature_finding.html#isolate_isotope_pattern"><code>isolate_isotope_pattern</code></a>. Here, three additional checks for an isotope pattern are implemented.</p>
+<p>The first one is <a href="/feature_finding.html#truncate"><code>truncate</code></a>. Here, one checks the seed position, whether it has a minimum to its left or right side. If a minimum is found, the isotope pattern is cut off at this position.</p>
 <p>The second one is a mass filter. If the seed has a mass of smaller than 1000, the intensity maximum is detected, and all smaller masses are discarded. This reflects the averagine distribution for small masses where no minimum on the left side can be found.</p>
-<p>The third one is <a href="/alphapept/feature_finding.html#check_averagine"><code>check_averagine</code></a> that relies on <a href="/alphapept/feature_finding.html#pattern_to_mz"><code>pattern_to_mz</code></a> and <a href="/alphapept/feature_finding.html#cosine_averagine"><code>cosine_averagine</code></a>. It is used to ensure that the extracted isotope pattern has a cosine correlation of the averagine isotope pattern of the same mass of at least 0.6.</p>
+<p>The third one is <a href="/feature_finding.html#check_averagine"><code>check_averagine</code></a> that relies on <a href="/feature_finding.html#pattern_to_mz"><code>pattern_to_mz</code></a> and <a href="/feature_finding.html#cosine_averagine"><code>cosine_averagine</code></a>. It is used to ensure that the extracted isotope pattern has a cosine correlation of the averagine isotope pattern of the same mass of at least 0.6.</p>
 <p>After the longest consistent isotope pattern is found, the hills are removed from the pre-isotope pattern, and the process is repeated until no more isotope patterns can be extracted from the pre-isotope patterns.</p>
 
 </div>
@@ -1405,7 +1405,7 @@ <h4 id="truncate" class="doc_header"><code>truncate</code><a href="https://githu
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Isotope-Patterns">Isotope Patterns<a class="anchor-link" href="#Isotope-Patterns"> </a></h2><p>The wrapper function <a href="/alphapept/feature_finding.html#get_isotope_patterns"><code>get_isotope_patterns</code></a> iterates over all pre_isotope_patterns.</p>
+<h2 id="Isotope-Patterns">Isotope Patterns<a class="anchor-link" href="#Isotope-Patterns"> </a></h2><p>The wrapper function <a href="/feature_finding.html#get_isotope_patterns"><code>get_isotope_patterns</code></a> iterates over all pre_isotope_patterns.</p>
 
 </div>
 </div>
diff --git a/docs/index.html b/docs/index.html
index 810d6db3..e8351379 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -8,14 +8,14 @@
 
 
 
-nb_path: "nbs\index.ipynb"
+nb_path: "nbs/index.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\index.ipynb
+# file to edit: nbs/index.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -35,7 +35,7 @@
 <img src="https://github.com/MannLabs/alphapept/workflows/Quick%20Test/badge.svg" alt="Quick Test">
 <img src="https://github.com/MannLabs/alphapept/workflows/Performance%20test/badge.svg" alt="Performance test">
 <img src="https://github.com/MannLabs/alphapept/workflows/Windows%20Installer/badge.svg" alt="Windows Installer"></p>
-<h1 id="AlphaPept">AlphaPept<a class="anchor-link" href="#AlphaPept"> </a></h1><p>{% include image.html align="center" file="/alphapept/images/alphapept_logo.png" %}</p>
+<h1 id="AlphaPept">AlphaPept<a class="anchor-link" href="#AlphaPept"> </a></h1><p>{% include image.html align="center" file="/images/alphapept_logo.png" %}</p>
 <blockquote><p>A modular, python-based framework to analyze mass spectrometry data. Powered by nbdev. Supercharged with numba.</p>
 </blockquote>
 
@@ -51,7 +51,7 @@ <h2 id="Documentation">Documentation<a class="anchor-link" href="#Documentation"
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Windows-Quickstart">Windows Quickstart<a class="anchor-link" href="#Windows-Quickstart"> </a></h2><p>{% include image.html width="480," align="center" max-width="480," file="/alphapept/images/alphapept_screen.png" %}</p>
+<h2 id="Windows-Quickstart">Windows Quickstart<a class="anchor-link" href="#Windows-Quickstart"> </a></h2><p>{% include image.html align="center" max-width="480," file="/images/alphapept_screen.png" %}</p>
 <ol>
 <li>Download the latest installer <a href="https://github.com/MannLabs/alphapept/releases/latest">here</a>, install and click the shortcut on the desktop. A browser window with the AlphaPept interface should open. In case Windows Firewall asks for network access for AlphaPept, please allow.</li>
 <li>In the <code>New Experiment</code> select a folder with raw files and FASTA files.</li>
@@ -154,7 +154,7 @@ <h2 id="How-to-use">How to use<a class="anchor-link" href="#How-to-use"> </a></h
 <li>Python: Use python modules to build individual workflows. Useful when building customized pipelines and using Python as a scripting language or when implementing new ideas. </li>
 </ul>
 <h3 id="Windows-Standalone-Installation">Windows Standalone Installation<a class="anchor-link" href="#Windows-Standalone-Installation"> </a></h3><p>For the <a href="https://github.com/MannLabs/alphapept/releases/latest">windows installation</a>, simply click on the shortcut after installation. The windows installation also installs the command-line tool so that you can call alphapept via <code>alphapept</code> in the command line.</p>
-<p>{% include image.html width="480," align="center" max-width="480," file="/alphapept/images/alphapept_cmd.png" %}</p>
+<p>{% include image.html align="center" max-width="480," file="/images/alphapept_cmd.png" %}</p>
 <h3 id="Python-Package">Python Package<a class="anchor-link" href="#Python-Package"> </a></h3><p>Once AlphaPept is correctly installed, you can use it like any other python module.</p>
 
 </div>
diff --git a/docs/interface.html b/docs/interface.html
index ff88667e..7ee14478 100644
--- a/docs/interface.html
+++ b/docs/interface.html
@@ -8,14 +8,14 @@
 
 
 
-nb_path: "nbs\11_interface.ipynb"
+nb_path: "nbs/11_interface.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\11_interface.ipynb
+# file to edit: nbs/11_interface.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
diff --git a/docs/io.html b/docs/io.html
index d39dae2a..2ca22272 100644
--- a/docs/io.html
+++ b/docs/io.html
@@ -8,14 +8,14 @@
 
 
 
-nb_path: "nbs\02_io.ipynb"
+nb_path: "nbs/02_io.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\02_io.ipynb
+# file to edit: nbs/02_io.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -524,7 +524,7 @@ <h2 id="Preprocessing-data">Preprocessing data<a class="anchor-link" href="#Prep
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Centroiding-profile-data">Centroiding profile data<a class="anchor-link" href="#Centroiding-profile-data"> </a></h3><p>Importing raw data frequently results in profile data. When having profile data, Alphapept first needs to perform centroiding to use this data properly. For this, it needs to search local maxima ("peaks") of the intensity as a function of m/z. For this AlphaPept uses the function <a href="/alphapept/io.html#get_peaks"><code>get_peaks</code></a>. A peak is described by three points, the <code>start</code> of the peak, the <code>center</code> and the <code>end</code>. The function accepts an intensity array and calculates the delta (gradient) between consecutive datapoints to determine the start, center and end.</p>
+<h3 id="Centroiding-profile-data">Centroiding profile data<a class="anchor-link" href="#Centroiding-profile-data"> </a></h3><p>Importing raw data frequently results in profile data. When having profile data, Alphapept first needs to perform centroiding to use this data properly. For this, it needs to search local maxima ("peaks") of the intensity as a function of m/z. For this AlphaPept uses the function <a href="/io.html#get_peaks"><code>get_peaks</code></a>. A peak is described by three points, the <code>start</code> of the peak, the <code>center</code> and the <code>end</code>. The function accepts an intensity array and calculates the delta (gradient) between consecutive datapoints to determine the start, center and end.</p>
 
 </div>
 </div>
@@ -611,7 +611,7 @@ <h4 id="get_peaks" class="doc_header"><code>get_peaks</code><a href="https://git
 <li>Three or more data points: Gaussian estimation of the center position.</li>
 </ul>
 <p>For the Gaussian estimation, only the three central points are used to fit a Gaussian Peak shape. The Gaussian is then approximated with the logarithm.</p>
-<p>The gaussian estimator is defined in <a href="/alphapept/io.html#gaussian_estimator"><code>gaussian_estimator</code></a> and is used by the wrapper <a href="/alphapept/io.html#get_centroid"><code>get_centroid</code></a>.</p>
+<p>The gaussian estimator is defined in <a href="/io.html#gaussian_estimator"><code>gaussian_estimator</code></a> and is used by the wrapper <a href="/io.html#get_centroid"><code>get_centroid</code></a>.</p>
 
 </div>
 </div>
@@ -821,7 +821,7 @@ <h4 id="centroid_data" class="doc_header"><code>centroid_data</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Trimming-spectra-to-retain-the-n-most-intense-peaks">Trimming spectra to retain the <code>n</code> most intense peaks<a class="anchor-link" href="#Trimming-spectra-to-retain-the-n-most-intense-peaks"> </a></h3><p><a href="/alphapept/io.html#get_most_abundant"><code>get_most_abundant</code></a>: In order to save spectra in a more memory efficient form, we only keep the n most abundant peaks. This allows us to save data in a fast accessible matrix format.</p>
+<h3 id="Trimming-spectra-to-retain-the-n-most-intense-peaks">Trimming spectra to retain the <code>n</code> most intense peaks<a class="anchor-link" href="#Trimming-spectra-to-retain-the-n-most-intense-peaks"> </a></h3><p><a href="/io.html#get_most_abundant"><code>get_most_abundant</code></a>: In order to save spectra in a more memory efficient form, we only keep the n most abundant peaks. This allows us to save data in a fast accessible matrix format.</p>
 
 </div>
 </div>
@@ -862,7 +862,7 @@ <h4 id="get_most_abundant" class="doc_header"><code>get_most_abundant</code><a h
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
 <p>For saving, we are currently relying on the hdf-container (see below).</p>
-<p>While we could, in principle, store the mz and int arrays as a list of variable length, this will come at a performance decrease. We, therefore, create an array of the dimensions of the n most abundant peaks and the number of spectra with the function <a href="/alphapept/io.html#list_to_numpy_f32"><code>list_to_numpy_f32</code></a> and fill the unoccupied cells with <code>-1</code>. This allows an increase in accessing times at the cost of additional disk space.</p>
+<p>While we could, in principle, store the mz and int arrays as a list of variable length, this will come at a performance decrease. We, therefore, create an array of the dimensions of the n most abundant peaks and the number of spectra with the function <a href="/io.html#list_to_numpy_f32"><code>list_to_numpy_f32</code></a> and fill the unoccupied cells with <code>-1</code>. This allows an increase in accessing times at the cost of additional disk space.</p>
 
 </div>
 </div>
@@ -1091,7 +1091,7 @@ <h3 id="The-final-.ms_data.hdf-file">The final <code>.ms_data.hdf</code> file<a
 
 
 <div class="output_markdown rendered_html output_subarea ">
-<h2 id="MS_Data_File" class="doc_header"><code>class</code> <code>MS_Data_File</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/io.py#L984" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>MS_Data_File</code>(<strong><code>file_name</code></strong>:<code>str</code>, <strong><code>is_read_only</code></strong>:<code>bool</code>=<em><code>True</code></em>, <strong><code>is_new_file</code></strong>:<code>bool</code>=<em><code>False</code></em>, <strong><code>is_overwritable</code></strong>:<code>bool</code>=<em><code>False</code></em>) :: <a href="/alphapept/io.html#HDF_File"><code>HDF_File</code></a></p>
+<h2 id="MS_Data_File" class="doc_header"><code>class</code> <code>MS_Data_File</code><a href="https://github.com/mannlabs/alphapept/tree/master/alphapept/io.py#L984" class="source_link" style="float:right">[source]</a></h2><blockquote><p><code>MS_Data_File</code>(<strong><code>file_name</code></strong>:<code>str</code>, <strong><code>is_read_only</code></strong>:<code>bool</code>=<em><code>True</code></em>, <strong><code>is_new_file</code></strong>:<code>bool</code>=<em><code>False</code></em>, <strong><code>is_overwritable</code></strong>:<code>bool</code>=<em><code>False</code></em>) :: <a href="/io.html#HDF_File"><code>HDF_File</code></a></p>
 </blockquote>
 <p>A generic class to store and retrieve on-disk
 data with an HDF container.</p>
diff --git a/docs/matching.html b/docs/matching.html
index 70ce3fd7..c689d552 100644
--- a/docs/matching.html
+++ b/docs/matching.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to matching"
 description: "Functions related to matching"
-nb_path: "nbs\09_matching.ipynb"
+nb_path: "nbs/09_matching.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\09_matching.ipynb
+# file to edit: nbs/09_matching.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
diff --git a/docs/quantification.html b/docs/quantification.html
index 590cdd45..4d0229a2 100644
--- a/docs/quantification.html
+++ b/docs/quantification.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to quantification"
 description: "Functions related to quantification"
-nb_path: "nbs\08_quantification.ipynb"
+nb_path: "nbs/08_quantification.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\08_quantification.ipynb
+# file to edit: nbs/08_quantification.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
diff --git a/docs/recalibration.html b/docs/recalibration.html
index 8367fda4..da7f3eb2 100644
--- a/docs/recalibration.html
+++ b/docs/recalibration.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to recalibrating"
 description: "Functions related to recalibrating"
-nb_path: "nbs\07_recalibration.ipynb"
+nb_path: "nbs/07_recalibration.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\07_recalibration.ipynb
+# file to edit: nbs/07_recalibration.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
diff --git a/docs/score.html b/docs/score.html
index 16c2db6b..e97d5d3f 100644
--- a/docs/score.html
+++ b/docs/score.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to the score"
 description: "Functions related to the score"
-nb_path: "nbs\06_score.ipynb"
+nb_path: "nbs/06_score.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\06_score.ipynb
+# file to edit: nbs/06_score.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -47,8 +47,8 @@
 <div class="text_cell_render border-box-sizing rendered_html">
 <h2 id="Filtering">Filtering<a class="anchor-link" href="#Filtering"> </a></h2><p>The filtering functions are essential base functions for scoring in AlphaPept. They make sure that only the 'best precursor per spectum' and the 'best spectrum per precursor' is used.</p>
 <p>Recall from the search that when having feautres, <code>raw_idx</code> refers to the actual index from the raw data. Otherwise it is<code>query_data</code>.</p>
-<p>For filtering, we have several functions. When applying for a score, we first use <a href="/alphapept/score.html#filter_score"><code>filter_score</code></a> and then <a href="/alphapept/score.html#filter_precursor"><code>filter_precursor</code></a>.
-<a href="/alphapept/score.html#filter_score"><code>filter_score</code></a> is keeping the best score per experimental spectrum. First we rank by score for each <code>query_idx</code>. As we have multiple hits for each experimental spectrum from the search we only want to keep the best one.</p>
+<p>For filtering, we have several functions. When applying for a score, we first use <a href="/score.html#filter_score"><code>filter_score</code></a> and then <a href="/score.html#filter_precursor"><code>filter_precursor</code></a>.
+<a href="/score.html#filter_score"><code>filter_score</code></a> is keeping the best score per experimental spectrum. First we rank by score for each <code>query_idx</code>. As we have multiple hits for each experimental spectrum from the search we only want to keep the best one.</p>
 <p>When performing feature finding, we assign multiple possible features to each experimental spectrum. The idea here is that a spectrum could originate from various precursors. To disentangle these psms we can use the following modes:</p>
 <ul>
 <li><code>single</code>: This mode will only keep one feature per experimental spectrum (the one with the highest score and the closest distance). Each feature can only occur once.</li>
@@ -127,7 +127,7 @@ <h2 id="Q-Values">Q-Values<a class="anchor-link" href="#Q-Values"> </a></h2>
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p><a href="/alphapept/score.html#get_q_values"><code>get_q_values</code></a> is used to calculate q-values from FDR values. The direct relationship is illustrated further down in the notebook.</p>
+<p><a href="/score.html#get_q_values"><code>get_q_values</code></a> is used to calculate q-values from FDR values. The direct relationship is illustrated further down in the notebook.</p>
 
 </div>
 </div>
@@ -243,7 +243,7 @@ <h4 id="cut_fdr" class="doc_header"><code>cut_fdr</code><a href="https://github.
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>Application of the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function to the simulated target-decoy competition dataset saved in <code>TDC</code>:</p>
+<p>Application of the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function to the simulated target-decoy competition dataset saved in <code>TDC</code>:</p>
 
 </div>
 </div>
@@ -329,12 +329,12 @@ <h4 id="cut_fdr" class="doc_header"><code>cut_fdr</code><a href="https://github.
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Global-FDR">Global FDR<a class="anchor-link" href="#Global-FDR"> </a></h2><p>The <a href="/alphapept/score.html#cut_global_fdr"><code>cut_global_fdr</code></a> function has two specific applications:</p>
+<h2 id="Global-FDR">Global FDR<a class="anchor-link" href="#Global-FDR"> </a></h2><p>The <a href="/score.html#cut_global_fdr"><code>cut_global_fdr</code></a> function has two specific applications:</p>
 <ol>
 <li><strong>Estimate q-values on the peptide and protein level</strong> <br/>
-The concept here is based on selecting the best scoring precursor per peptide (or protein) to then estimate the FDR by target-decoy competition using the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function.</li>
+The concept here is based on selecting the best scoring precursor per peptide (or protein) to then estimate the FDR by target-decoy competition using the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function.</li>
 <li><strong>Estimate q-values across an entire dataset on either precursor, peptide or protein level</strong> <br/>
-The concept here is based on selecting the best scoring precursor, peptide or protein signal across an entire dataset to then estimate the FDR by target-decoy competition using the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function.</li>
+The concept here is based on selecting the best scoring precursor, peptide or protein signal across an entire dataset to then estimate the FDR by target-decoy competition using the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function.</li>
 </ol>
 <p>This strategy was extensively tested and discussed in the following publications:</p>
 <blockquote><p>Nesvizhskii, Alexey I. "A survey of computational methods and error rate estimation procedures for peptide and protein identification in shotgun proteomics." Journal of proteomics vol. 73,11 (2010):2092-123. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2956504/">https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2956504/</a> &gt; Savitski, Mikhail M et al. "A Scalable Approach for Protein False Discovery Rate Estimation in Large Proteomic Data Sets." Molecular &amp; cellular proteomics :MCP vol. 14,9 (2015): 2394-404. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4563723/">https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4563723/</a>&gt; The, Matthew et al. "Fast and Accurate Protein False Discovery Rates on Large-Scale Proteomics Data Sets with Percolator 3.0." Journal of the American Society for Mass Spectrometry vol. 27,11 (2016):1719-1727. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5059416/">https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5059416/</a>&gt; Gupta, Nitin, and Pavel A Pevzner. "False discovery rates of protein identifications:a strike against the two-peptide rule." Journal of proteome research vol. 8,9 (2009): 4173-81. <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3398614/">https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3398614/</a></p>
@@ -384,7 +384,7 @@ <h4 id="cut_global_fdr" class="doc_header"><code>cut_global_fdr</code><a href="h
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>Application of the <a href="/alphapept/score.html#cut_global_fdr"><code>cut_global_fdr</code></a> function to the simulated protein-level target-decoy competition dataset saved in <code>TDC_prot</code>:</p>
+<p>Application of the <a href="/score.html#cut_global_fdr"><code>cut_global_fdr</code></a> function to the simulated protein-level target-decoy competition dataset saved in <code>TDC_prot</code>:</p>
 
 </div>
 </div>
@@ -477,9 +477,9 @@ <h2 id="Scoring">Scoring<a class="anchor-link" href="#Scoring"> </a></h2>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
 <h3 id="X!tandem-scoring">X!tandem scoring<a class="anchor-link" href="#X!tandem-scoring"> </a></h3><ul>
-<li><p><a href="/alphapept/score.html#get_x_tandem_score"><code>get_x_tandem_score</code></a> performs scoring of PSMs according to the X!tandem strategy:</p>
+<li><p><a href="/score.html#get_x_tandem_score"><code>get_x_tandem_score</code></a> performs scoring of PSMs according to the X!tandem strategy:</p>
 </li>
-<li><p><a href="/alphapept/score.html#score_x_tandem"><code>score_x_tandem</code></a> first calls <a href="/alphapept/score.html#get_x_tandem_score"><code>get_x_tandem_score</code></a> and and subsequently applies the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function to filter PSMs at the specified <code>fdr_level</code>.</p>
+<li><p><a href="/score.html#score_x_tandem"><code>score_x_tandem</code></a> first calls <a href="/score.html#get_x_tandem_score"><code>get_x_tandem_score</code></a> and and subsequently applies the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function to filter PSMs at the specified <code>fdr_level</code>.</p>
 </li>
 </ul>
 <blockquote><p>X!Tandem, Craig,R. and Beavis,R.C. (2003) Rapid Commun. Mass Spectrom., 17, 2310-2316</p>
@@ -570,7 +570,7 @@ <h4 id="filter_with_x_tandem" class="doc_header"><code>filter_with_x_tandem</cod
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Score-and-filter-PSMs-by-any-specified-score">Score and filter PSMs by any specified score<a class="anchor-link" href="#Score-and-filter-PSMs-by-any-specified-score"> </a></h3><p><a href="/alphapept/score.html#score_psms"><code>score_psms</code></a> uses the specified <a href="/alphapept/score.html"><code>score</code></a> and applies the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function to filter PSMs at the specified <code>fdr_level</code>. <a href="/alphapept/score.html#filter_score"><code>filter_score</code></a> and <a href="/alphapept/score.html#filter_precursor"><code>filter_precursor</code></a> are applied to only report the best PSM per acquired spectrum and the best signal per precursor (i.e. sequence + charge combination).</p>
+<h3 id="Score-and-filter-PSMs-by-any-specified-score">Score and filter PSMs by any specified score<a class="anchor-link" href="#Score-and-filter-PSMs-by-any-specified-score"> </a></h3><p><a href="/score.html#score_psms"><code>score_psms</code></a> uses the specified <a href="/score.html"><code>score</code></a> and applies the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function to filter PSMs at the specified <code>fdr_level</code>. <a href="/score.html#filter_score"><code>filter_score</code></a> and <a href="/score.html#filter_precursor"><code>filter_precursor</code></a> are applied to only report the best PSM per acquired spectrum and the best signal per precursor (i.e. sequence + charge combination).</p>
 
 </div>
 </div>
@@ -609,9 +609,9 @@ <h4 id="score_psms" class="doc_header"><code>score_psms</code><a href="https://g
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
 <h2 id="Machine-learning-based-scoring-of-PSMs">Machine learning based scoring of PSMs<a class="anchor-link" href="#Machine-learning-based-scoring-of-PSMs"> </a></h2><ul>
-<li><p><a href="/alphapept/score.html#get_ML_features"><code>get_ML_features</code></a> extracts additional scoring metrics for the machine learning, including the number of amino acids per precursor, the number of missed cleavages and the logarithmic number of times the same peptide occurs in the set of PSMs</p>
+<li><p><a href="/score.html#get_ML_features"><code>get_ML_features</code></a> extracts additional scoring metrics for the machine learning, including the number of amino acids per precursor, the number of missed cleavages and the logarithmic number of times the same peptide occurs in the set of PSMs</p>
 </li>
-<li><p><a href="/alphapept/score.html#train_RF"><code>train_RF</code></a> trains a random forest classifier for scoring all PSMs. For this, we use the scikit-learn library.</p>
+<li><p><a href="/score.html#train_RF"><code>train_RF</code></a> trains a random forest classifier for scoring all PSMs. For this, we use the scikit-learn library.</p>
 <ul>
 <li>First, a machine learning pipeline is created including the sklearn <code>StandardScaler</code> and <code>RandomForestClassifier</code>. The <code>StandardScaler</code> is used to standardize all features by removing the mean and scaling to unit variance. For details on the <code>RandomForestClassifier</code> see: <a href="https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html">https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html</a>.</li>
 <li>Next, a grid search is initialized for testing the hyperparameter space (<code>max_depth</code> and <code>max_leaf_nodes</code>) of the random forest classifier by a 5-fold cross-validation using <code>GridSearchCV</code>.</li>
@@ -623,7 +623,7 @@ <h2 id="Machine-learning-based-scoring-of-PSMs">Machine learning based scoring o
 <li>Finally the function returns the trained random forest classifier for subsequent application to the entire set of PSMs or for transfering to a different dataset. </li>
 </ul>
 </li>
-<li><p><a href="/alphapept/score.html#score_ML"><code>score_ML</code></a> applies a classifier trained by <a href="/alphapept/score.html#train_RF"><code>train_RF</code></a> to a complete set of PSMs. It calls the <a href="/alphapept/score.html#cut_fdr"><code>cut_fdr</code></a> function and filters for the specified <code>fdr_level</code>. <a href="/alphapept/score.html#filter_score"><code>filter_score</code></a> and <a href="/alphapept/score.html#filter_precursor"><code>filter_precursor</code></a> are applied to only report the best PSM per acquired spectrum and the best signal per precursor (i.e. sequence + charge combination).</p>
+<li><p><a href="/score.html#score_ML"><code>score_ML</code></a> applies a classifier trained by <a href="/score.html#train_RF"><code>train_RF</code></a> to a complete set of PSMs. It calls the <a href="/score.html#cut_fdr"><code>cut_fdr</code></a> function and filters for the specified <code>fdr_level</code>. <a href="/score.html#filter_score"><code>filter_score</code></a> and <a href="/score.html#filter_precursor"><code>filter_precursor</code></a> are applied to only report the best PSM per acquired spectrum and the best signal per precursor (i.e. sequence + charge combination).</p>
 </li>
 </ul>
 
diff --git a/docs/search.html b/docs/search.html
index 15fa0101..bc3f5aa5 100644
--- a/docs/search.html
+++ b/docs/search.html
@@ -8,14 +8,14 @@
 
 summary: "Functions related to the search"
 description: "Functions related to the search"
-nb_path: "nbs\05_search.ipynb"
+nb_path: "nbs/05_search.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\05_search.ipynb
+# file to edit: nbs/05_search.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -206,9 +206,9 @@ <h4 id="compare_frags" class="doc_header"><code>compare_frags</code><a href="htt
 
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h2 id="Comparing-Spectra">Comparing Spectra<a class="anchor-link" href="#Comparing-Spectra"> </a></h2><p>To compare multiple spectra against a database, we first need some helper functions. Per default, AlphaPept calculates in Dalton. To use ppm boundaries, we need the function <a href="/alphapept/search.html#ppm_to_dalton"><code>ppm_to_dalton</code></a> for conversion.</p>
-<p>To minimize the search space, we typically only compare spectra with precursors in the same mass range as defined by <code>m_offset</code>. To look up the limits for search, we define the function <a href="/alphapept/search.html#get_idxs"><code>get_idxs</code></a>, which is a wrapper to the fast <code>searchsorted</code> method from NumPy.</p>
-<p>The actual search takes place in <a href="/alphapept/search.html#compare_specs_single"><code>compare_specs_single</code></a> and <a href="/alphapept/search.html#compare_specs_parallel"><code>compare_specs_parallel</code></a>, a single-core and multicore method for comparing spectra.</p>
+<h2 id="Comparing-Spectra">Comparing Spectra<a class="anchor-link" href="#Comparing-Spectra"> </a></h2><p>To compare multiple spectra against a database, we first need some helper functions. Per default, AlphaPept calculates in Dalton. To use ppm boundaries, we need the function <a href="/search.html#ppm_to_dalton"><code>ppm_to_dalton</code></a> for conversion.</p>
+<p>To minimize the search space, we typically only compare spectra with precursors in the same mass range as defined by <code>m_offset</code>. To look up the limits for search, we define the function <a href="/search.html#get_idxs"><code>get_idxs</code></a>, which is a wrapper to the fast <code>searchsorted</code> method from NumPy.</p>
+<p>The actual search takes place in <a href="/search.html#compare_specs_single"><code>compare_specs_single</code></a> and <a href="/search.html#compare_specs_parallel"><code>compare_specs_parallel</code></a>, a single-core and multicore method for comparing spectra.</p>
 
 </div>
 </div>
@@ -400,7 +400,7 @@ <h2 id="Extracting-columns-for-scoring">Extracting columns for scoring<a class="
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Frag-Delta">Frag Delta<a class="anchor-link" href="#Frag-Delta"> </a></h3><p><a href="/alphapept/search.html#frag_delta"><code>frag_delta</code></a> calculates the the substracts the experimental fragment masses from the theoretical fragment masses for each hit.</p>
+<h3 id="Frag-Delta">Frag Delta<a class="anchor-link" href="#Frag-Delta"> </a></h3><p><a href="/search.html#frag_delta"><code>frag_delta</code></a> calculates the the substracts the experimental fragment masses from the theoretical fragment masses for each hit.</p>
 
 </div>
 </div>
diff --git a/docs/settings.html b/docs/settings.html
index a041b8c7..a4b5e62e 100644
--- a/docs/settings.html
+++ b/docs/settings.html
@@ -8,14 +8,14 @@
 
 summary: "A template for settings"
 description: "A template for settings"
-nb_path: "nbs\00_settings.ipynb"
+nb_path: "nbs/00_settings.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\00_settings.ipynb
+# file to edit: nbs/00_settings.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
@@ -579,7 +579,8 @@ <h3 id="FASTA-settings">FASTA settings<a class="anchor-link" href="#FASTA-settin
     tmt2&lt;^: TMT duplex on peptide N-terminus
     tmt6&lt;^: TMT sixplex/tenplex on peptide N-terminus
 mods_variable_terminal_prot:
-  default: []
+  default:
+  - a&lt;^
   description: Varibale terminal modifications on proteins.
   type: checkgroup
   value:
diff --git a/docs/speed.html b/docs/speed.html
index c925b655..5800620d 100644
--- a/docs/speed.html
+++ b/docs/speed.html
@@ -8,14 +8,14 @@
 
 
 
-nb_path: "nbs\12_speed.ipynb"
+nb_path: "nbs/12_speed.ipynb"
 ---
 <!--
 
 #################################################
 ### THIS FILE WAS AUTOGENERATED! DO NOT EDIT! ###
 #################################################
-# file to edit: nbs\12_speed.ipynb
+# file to edit: nbs/12_speed.ipynb
 # command to build the docs after a change: nbdev_build_docs
 
 -->
diff --git a/installer/one_click_windows/alphapept_innoinstaller.iss b/installer/one_click_windows/alphapept_innoinstaller.iss
index 5ed295a0..ccd22abf 100644
--- a/installer/one_click_windows/alphapept_innoinstaller.iss
+++ b/installer/one_click_windows/alphapept_innoinstaller.iss
@@ -2,7 +2,7 @@
 ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
 
 #define MyAppName "AlphaPept"
-#define MyAppVersion "0.3.21"
+#define MyAppVersion "0.3.22"
 #define MyAppPublisher "MannLabs"
 #define MyAppURL "https://github.com/MannLabs/alphapept"
 #define MyAppExeName "alphapept.exe"
diff --git a/installer/one_click_windows/create_installer_windows.bat b/installer/one_click_windows/create_installer_windows.bat
index 3a7c108f..5c87a172 100644
--- a/installer/one_click_windows/create_installer_windows.bat
+++ b/installer/one_click_windows/create_installer_windows.bat
@@ -11,7 +11,7 @@ call DEL /F/Q/S dist > NUL
 call RMDIR /Q/S build
 call RMDIR /Q/S dist
 call python setup.py sdist bdist_wheel
-call pip install dist/alphapept-0.3.21-py3-none-any.whl
+call pip install dist/alphapept-0.3.22-py3-none-any.whl
 call pip install pyinstaller==4.2
 call cd installer/one_click_windows
 call pyinstaller ../alphapept.spec -y
diff --git a/nbs/00_settings.ipynb b/nbs/00_settings.ipynb
index 0b2e2c75..84ed26ce 100644
--- a/nbs/00_settings.ipynb
+++ b/nbs/00_settings.ipynb
@@ -412,7 +412,7 @@
     "fasta[\"mods_variable_terminal\"]  = {'type':'checkgroup', 'value':mods_terminal.copy(), 'default':[], 'description':\"Varibale terminal modifications.\"}\n",
     "\n",
     "fasta[\"mods_fixed_terminal_prot\"] = {'type':'checkgroup', 'value':mods_protein.copy(), 'default':[],'description':\"Fixed terminal modifications on proteins.\"}\n",
-    "fasta[\"mods_variable_terminal_prot\"]  = {'type':'checkgroup', 'value':mods_protein.copy(), 'default':[], 'description':\"Varibale terminal modifications on proteins.\"}\n",
+    "fasta[\"mods_variable_terminal_prot\"]  = {'type':'checkgroup', 'value':mods_protein.copy(), 'default':['a<^'], 'description':\"Varibale terminal modifications on proteins.\"}\n",
     "\n",
     "fasta[\"num_missed_cleavages\"] = {'type':'spinbox', 'min':0, 'max':99, 'default':2, 'description':\"Number of missed cleavages.\"}\n",
     "fasta[\"min_length\"] = {'type':'spinbox', 'min':6, 'max':99, 'default':6, 'description':\"Minimum peptide length.\"}\n",
@@ -580,7 +580,8 @@
       "    tmt2<^: TMT duplex on peptide N-terminus\n",
       "    tmt6<^: TMT sixplex/tenplex on peptide N-terminus\n",
       "mods_variable_terminal_prot:\n",
-      "  default: []\n",
+      "  default:\n",
+      "  - a<^\n",
       "  description: Varibale terminal modifications on proteins.\n",
       "  type: checkgroup\n",
       "  value:\n",
@@ -1183,7 +1184,8 @@
       "Converted 10_constants.ipynb.\n",
       "Converted 11_interface.ipynb.\n",
       "Converted 12_speed.ipynb.\n",
-      "Converted index.ipynb.\n"
+      "Converted index.ipynb.\n",
+      "Converted Untitled.ipynb.\n"
      ]
     }
    ],
diff --git a/nbs/03_fasta.ipynb b/nbs/03_fasta.ipynb
index 25a2ab71..a0233d07 100644
--- a/nbs/03_fasta.ipynb
+++ b/nbs/03_fasta.ipynb
@@ -545,6 +545,36 @@
     "add_fixed_mods(peptide_list, mods_fixed)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['caAbBcCDEF']"
+      ]
+     },
+     "execution_count": null,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "mods_fixed = ['aA','cC','bB']\n",
+    "peptide_list = ['cABCDEF']\n",
+    "\n",
+    "add_fixed_mods(peptide_list, mods_fixed)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -993,19 +1023,28 @@
     "def generate_peptides(peptide, **kwargs):\n",
     "    \"\"\"\n",
     "    Wrapper to get modified peptides from a peptide\n",
+    "    \n",
+    "    TODO:\n",
+    "    \n",
+    "    There can be some edge-cases which are not defined yet.\n",
+    "    Example:\n",
+    "    Setting the same fixed modification - once for all peptides and once for only terminal for the protein.\n",
+    "    The modification will thenbe applied twice.\n",
+    "    \n",
     "    \"\"\"\n",
     "    mod_peptide = add_fixed_mods_terminal([peptide], kwargs['mods_fixed_terminal_prot'])\n",
     "    mod_peptide = add_variable_mods_terminal(mod_peptide, kwargs['mods_variable_terminal_prot'])\n",
-    "\n",
+    "    \n",
     "    peptides = []\n",
     "    [peptides.extend(cleave_sequence(_, **kwargs)) for _ in mod_peptide]\n",
-    "    \n",
+    "\n",
     "    peptides = [_ for _ in peptides if check_peptide(_, constants.AAs)]\n",
     "    \n",
     "    max_isoforms = kwargs['max_isoforms']\n",
-    "    \n",
+    "\n",
     "    all_peptides = []\n",
     "    for peptide in peptides: #1 per, limit the number of isoforms\n",
+    "\n",
     "        #Regular peptides\n",
     "        mod_peptides = add_fixed_mods([peptide], **kwargs)\n",
     "        mod_peptides = add_fixed_mods_terminal(mod_peptides, **kwargs)\n",
@@ -1035,7 +1074,7 @@
     "\n",
     "def check_peptide(peptide, AAs):\n",
     "    \n",
-    "    if set(peptide).issubset(AAs):\n",
+    "    if set([_ for _ in peptide if _.isupper()]).issubset(AAs):\n",
     "        return True\n",
     "    else:\n",
     "        return False"
@@ -1049,7 +1088,14 @@
     {
      "data": {
       "text/plain": [
-       "['PEPTIDEM', 'PEPTIDEoxM', 'MEDITPEP_decoy', 'oxMEDITPEP_decoy']"
+       "['PEPTIDEM',\n",
+       " 'PEPTIDEoxM',\n",
+       " 'MEDITPEP_decoy',\n",
+       " 'oxMEDITPEP_decoy',\n",
+       " 'aPEPTIDEM',\n",
+       " 'aPEPTIDEoxM',\n",
+       " 'MEDITPEaP_decoy',\n",
+       " 'oxMEDITPEaP_decoy']"
       ]
      },
      "execution_count": null,
@@ -1069,7 +1115,7 @@
     "kwargs[\"mods_fixed\"] = [\"cC\"]\n",
     "kwargs[\"mods_fixed_terminal\"] = []\n",
     "kwargs[\"mods_fixed_terminal_prot\"] = []\n",
-    "kwargs[\"mods_variable_terminal_prot\"]  = []\n",
+    "kwargs[\"mods_variable_terminal_prot\"]  = ['a<^']\n",
     "kwargs[\"max_isoforms\"] = 1024\n",
     "kwargs[\"limit_modifications\"] = None\n",
     "\n",
@@ -1155,7 +1201,7 @@
     {
      "data": {
       "text/plain": [
-       "799.3599642034599"
+       "799.35996420346"
       ]
      },
      "execution_count": null,
@@ -1312,17 +1358,17 @@
      "data": {
       "text/plain": [
        "{'b1': 98.06004032687,\n",
-       " 'b2': 227.10263342686997,\n",
+       " 'b2': 227.10263342687,\n",
        " 'b3': 324.15539728686997,\n",
        " 'b4': 425.20307578687,\n",
        " 'b5': 538.28713978687,\n",
        " 'b6': 653.31408288687,\n",
        " 'y1': 148.06043425033,\n",
        " 'y2': 263.08737735033,\n",
-       " 'y3': 376.1714413503299,\n",
-       " 'y4': 477.21911985032995,\n",
-       " 'y5': 574.2718837103299,\n",
-       " 'y6': 703.3144768103299}"
+       " 'y3': 376.17144135033,\n",
+       " 'y4': 477.21911985033,\n",
+       " 'y5': 574.27188371033,\n",
+       " 'y6': 703.31447681033}"
       ]
      },
      "execution_count": null,
@@ -1448,7 +1494,10 @@
     "    spectra = List()\n",
     "\n",
     "    for i in range(len(peptides)):\n",
-    "        spectra.append(get_spectrum(peptides[i], mass_dict))\n",
+    "        try:\n",
+    "            spectra.append(get_spectrum(peptides[i], mass_dict))\n",
+    "        except Exception: #TODO: This is to fix edge cases when having multiple modifications on the same AA.  \n",
+    "            pass\n",
     "\n",
     "    return spectra"
    ]
@@ -1462,7 +1511,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[(799.3599642034599, 'PEPTIDE', array([ 98.06004033, 148.06043425, 227.10263343, 263.08737735,\n",
+      "[(799.35996420346, 'PEPTIDE', array([ 98.06004033, 148.06043425, 227.10263343, 263.08737735,\n",
       "       324.15539729, 376.17144135, 425.20307579, 477.21911985,\n",
       "       538.28713979, 574.27188371, 653.31408289, 703.31447681]), array([ 1, -1,  2, -2,  3, -3,  4, -4,  5, -5,  6, -6], dtype=int8))]\n"
      ]
@@ -2197,7 +2246,8 @@
       "Converted 10_constants.ipynb.\n",
       "Converted 11_interface.ipynb.\n",
       "Converted 12_speed.ipynb.\n",
-      "Converted index.ipynb.\n"
+      "Converted index.ipynb.\n",
+      "Converted Untitled.ipynb.\n"
      ]
     }
    ],
diff --git a/nbs/10_constants.ipynb b/nbs/10_constants.ipynb
index 199e1322..77cddfaa 100644
--- a/nbs/10_constants.ipynb
+++ b/nbs/10_constants.ipynb
@@ -62,7 +62,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "{'G', 'D', 'V', 'K', 'A', 'N', 'P', 'E', 'Q', 'T', 'C', 'M', 'H', 'I', 'W', 'R', 'F', 'U', 'Y', 'S', 'L'}\n"
+      "{'P', 'I', 'A', 'L', 'M', 'N', 'F', 'D', 'G', 'S', 'Y', 'C', 'R', 'V', 'Q', 'U', 'T', 'H', 'K', 'W', 'E'}\n"
      ]
     }
    ],
@@ -90,60 +90,212 @@
     "\n",
     "mass_dict = Dict.empty(key_type=types.unicode_type, value_type=types.float64)\n",
     "\n",
-    "mass_dict[\"A\"] = 71.03711379999999\n",
+    "mass_dict[\"A\"] = 71.0371138\n",
     "mass_dict[\"C\"] = 103.0091845\n",
-    "mass_dict[\"D\"] = 115.02694309999998\n",
-    "mass_dict[\"E\"] = 129.04259309999998\n",
+    "mass_dict[\"D\"] = 115.0269431\n",
+    "mass_dict[\"E\"] = 129.0425931\n",
     "mass_dict[\"F\"] = 147.0684139\n",
     "mass_dict[\"G\"] = 57.02146373\n",
     "mass_dict[\"H\"] = 137.0589119\n",
-    "mass_dict[\"I\"] = 113.08406399999998\n",
-    "mass_dict[\"K\"] = 128.09496299999998\n",
-    "mass_dict[\"L\"] = 113.08406399999998\n",
-    "mass_dict[\"M\"] = 131.04048459999998\n",
-    "mass_dict[\"N\"] = 114.04292749999999\n",
+    "mass_dict[\"I\"] = 113.084064\n",
+    "mass_dict[\"K\"] = 128.094963\n",
+    "mass_dict[\"L\"] = 113.084064\n",
+    "mass_dict[\"M\"] = 131.0404846\n",
+    "mass_dict[\"N\"] = 114.0429275\n",
     "mass_dict[\"P\"] = 97.05276386\n",
-    "mass_dict[\"Q\"] = 128.05857749999998\n",
+    "mass_dict[\"Q\"] = 128.0585775\n",
     "mass_dict[\"R\"] = 156.101111\n",
     "mass_dict[\"S\"] = 87.03202843\n",
     "mass_dict[\"T\"] = 101.0476785\n",
     "mass_dict[\"U\"] = 150.9536333957\n",
     "mass_dict[\"V\"] = 99.06841392\n",
-    "mass_dict[\"W\"] = 186.07931299999998\n",
-    "mass_dict[\"Y\"] = 163.06332859999998\n",
+    "mass_dict[\"W\"] = 186.079313\n",
+    "mass_dict[\"Y\"] = 163.0633286\n",
     "mass_dict[\"cC\"] = 160.03064823\n",
-    "mass_dict[\"oxM\"] = 147.03539923\n",
-    "mass_dict[\"aN\"] = 156.05349219\n",
-    "mass_dict[\"amN\"] = 113.058911907\n",
-    "mass_dict[\"aK\"] = 170.10552768999997\n",
+    "mass_dict[\"oxM\"] = 147.03539923000002\n",
+    "mass_dict[\"aA\"] = 113.04767849000001\n",
+    "mass_dict[\"aC\"] = 145.01974919\n",
+    "mass_dict[\"aD\"] = 157.03750779\n",
+    "mass_dict[\"aE\"] = 171.05315779\n",
+    "mass_dict[\"aF\"] = 189.07897859\n",
+    "mass_dict[\"aG\"] = 99.03202842\n",
+    "mass_dict[\"aH\"] = 179.06947659\n",
+    "mass_dict[\"aI\"] = 155.09462869\n",
+    "mass_dict[\"aK\"] = 170.10552769\n",
+    "mass_dict[\"aL\"] = 155.09462869\n",
+    "mass_dict[\"aM\"] = 173.05104929\n",
+    "mass_dict[\"aN\"] = 156.05349219000001\n",
+    "mass_dict[\"aP\"] = 139.06332855\n",
+    "mass_dict[\"aQ\"] = 170.06914219\n",
+    "mass_dict[\"aR\"] = 198.11167569\n",
+    "mass_dict[\"aS\"] = 129.04259312\n",
+    "mass_dict[\"aT\"] = 143.05824319\n",
+    "mass_dict[\"aU\"] = 192.9641980857\n",
+    "mass_dict[\"aV\"] = 141.07897861\n",
+    "mass_dict[\"aW\"] = 228.08987769\n",
+    "mass_dict[\"aY\"] = 205.07389329\n",
+    "mass_dict[\"amA\"] = 70.053098207\n",
+    "mass_dict[\"amC\"] = 102.02516890700001\n",
+    "mass_dict[\"amD\"] = 114.042927507\n",
+    "mass_dict[\"amE\"] = 128.058577507\n",
+    "mass_dict[\"amF\"] = 146.084398307\n",
+    "mass_dict[\"amG\"] = 56.037448137\n",
+    "mass_dict[\"amH\"] = 136.074896307\n",
+    "mass_dict[\"amI\"] = 112.100048407\n",
+    "mass_dict[\"amK\"] = 127.11094740700001\n",
+    "mass_dict[\"amL\"] = 112.100048407\n",
+    "mass_dict[\"amM\"] = 130.056469007\n",
+    "mass_dict[\"amN\"] = 113.05891190700001\n",
+    "mass_dict[\"amP\"] = 96.068748267\n",
+    "mass_dict[\"amQ\"] = 127.07456190700002\n",
+    "mass_dict[\"amR\"] = 155.117095407\n",
+    "mass_dict[\"amS\"] = 86.048012837\n",
+    "mass_dict[\"amT\"] = 100.06366290700001\n",
+    "mass_dict[\"amU\"] = 149.9696178027\n",
+    "mass_dict[\"amV\"] = 98.084398327\n",
+    "mass_dict[\"amW\"] = 185.095297407\n",
+    "mass_dict[\"amY\"] = 162.079313007\n",
     "mass_dict[\"pS\"] = 166.99835935\n",
     "mass_dict[\"pT\"] = 181.01400942\n",
     "mass_dict[\"pY\"] = 243.02965952\n",
-    "mass_dict[\"deamN\"] = 115.02694309299999\n",
-    "mass_dict[\"deamNQ\"] = 129.042593093\n",
+    "mass_dict[\"deamN\"] = 115.026943093\n",
+    "mass_dict[\"deamNQ\"] = 129.04259309300002\n",
     "mass_dict[\"cmC\"] = 85.9826354\n",
-    "mass_dict[\"pgE\"] = 111.03202840999998\n",
-    "mass_dict[\"pgQ\"] = 111.03202839999999\n",
-    "mass_dict[\"tmt0N\"] = 338.1954054\n",
+    "mass_dict[\"pgE\"] = 111.03202841000001\n",
+    "mass_dict[\"pgQ\"] = 111.03202840000002\n",
+    "mass_dict[\"tmt0A\"] = 295.1895917\n",
+    "mass_dict[\"tmt0C\"] = 327.1616624\n",
+    "mass_dict[\"tmt0D\"] = 339.179421\n",
+    "mass_dict[\"tmt0E\"] = 353.195071\n",
+    "mass_dict[\"tmt0F\"] = 371.2208918\n",
+    "mass_dict[\"tmt0G\"] = 281.17394163\n",
+    "mass_dict[\"tmt0H\"] = 361.2113898\n",
+    "mass_dict[\"tmt0I\"] = 337.2365419\n",
     "mass_dict[\"tmt0K\"] = 352.2474409\n",
+    "mass_dict[\"tmt0L\"] = 337.2365419\n",
+    "mass_dict[\"tmt0M\"] = 355.1929625\n",
+    "mass_dict[\"tmt0N\"] = 338.1954054\n",
+    "mass_dict[\"tmt0P\"] = 321.20524176000004\n",
+    "mass_dict[\"tmt0Q\"] = 352.2110554\n",
+    "mass_dict[\"tmt0R\"] = 380.2535889\n",
+    "mass_dict[\"tmt0S\"] = 311.18450633\n",
+    "mass_dict[\"tmt0T\"] = 325.2001564\n",
+    "mass_dict[\"tmt0U\"] = 375.1061112957\n",
+    "mass_dict[\"tmt0V\"] = 323.22089182\n",
+    "mass_dict[\"tmt0W\"] = 410.2317909\n",
     "mass_dict[\"tmt0Y\"] = 387.2158065\n",
-    "mass_dict[\"tmt2N\"] = 339.1987603\n",
+    "mass_dict[\"tmt2A\"] = 296.1929466\n",
+    "mass_dict[\"tmt2C\"] = 328.16501730000004\n",
+    "mass_dict[\"tmt2D\"] = 340.1827759\n",
+    "mass_dict[\"tmt2E\"] = 354.1984259\n",
+    "mass_dict[\"tmt2F\"] = 372.2242467\n",
+    "mass_dict[\"tmt2G\"] = 282.17729653000004\n",
+    "mass_dict[\"tmt2H\"] = 362.2147447\n",
+    "mass_dict[\"tmt2I\"] = 338.2398968\n",
     "mass_dict[\"tmt2K\"] = 353.2507958\n",
-    "mass_dict[\"tmt2Y\"] = 388.21916139999996\n",
-    "mass_dict[\"tmt6N\"] = 343.20585969999996\n",
-    "mass_dict[\"tmt6K\"] = 357.25789519999995\n",
+    "mass_dict[\"tmt2L\"] = 338.2398968\n",
+    "mass_dict[\"tmt2M\"] = 356.1963174\n",
+    "mass_dict[\"tmt2N\"] = 339.1987603\n",
+    "mass_dict[\"tmt2P\"] = 322.20859666\n",
+    "mass_dict[\"tmt2Q\"] = 353.21441030000005\n",
+    "mass_dict[\"tmt2R\"] = 381.25694380000004\n",
+    "mass_dict[\"tmt2S\"] = 312.18786123\n",
+    "mass_dict[\"tmt2T\"] = 326.2035113\n",
+    "mass_dict[\"tmt2U\"] = 376.1094661957\n",
+    "mass_dict[\"tmt2V\"] = 324.22424672\n",
+    "mass_dict[\"tmt2W\"] = 411.23514580000005\n",
+    "mass_dict[\"tmt2Y\"] = 388.2191614\n",
+    "mass_dict[\"tmt6A\"] = 300.200046\n",
+    "mass_dict[\"tmt6C\"] = 332.1721167\n",
+    "mass_dict[\"tmt6D\"] = 344.1898753\n",
+    "mass_dict[\"tmt6E\"] = 358.2055253\n",
+    "mass_dict[\"tmt6F\"] = 376.2313461\n",
+    "mass_dict[\"tmt6G\"] = 286.18439593\n",
+    "mass_dict[\"tmt6H\"] = 366.2218441\n",
+    "mass_dict[\"tmt6I\"] = 342.2469962\n",
+    "mass_dict[\"tmt6K\"] = 357.2578952\n",
+    "mass_dict[\"tmt6L\"] = 342.2469962\n",
+    "mass_dict[\"tmt6M\"] = 360.2034168\n",
+    "mass_dict[\"tmt6N\"] = 343.2058597\n",
+    "mass_dict[\"tmt6P\"] = 326.21569606\n",
+    "mass_dict[\"tmt6Q\"] = 357.2215097\n",
+    "mass_dict[\"tmt6R\"] = 385.2640432\n",
+    "mass_dict[\"tmt6S\"] = 316.19496062999997\n",
+    "mass_dict[\"tmt6T\"] = 330.2106107\n",
+    "mass_dict[\"tmt6U\"] = 380.11656559569997\n",
+    "mass_dict[\"tmt6V\"] = 328.23134612\n",
+    "mass_dict[\"tmt6W\"] = 415.2422452\n",
     "mass_dict[\"tmt6Y\"] = 392.2262608\n",
-    "mass_dict[\"itraq4KN\"] = 258.14533789999996\n",
-    "mass_dict[\"itraq4K\"] = 272.19737339999995\n",
-    "mass_dict[\"itraq4Y\"] = 307.165739\n",
+    "mass_dict[\"itraq4KA\"] = 215.13952419999998\n",
+    "mass_dict[\"itraq4KC\"] = 247.1115949\n",
+    "mass_dict[\"itraq4KD\"] = 259.1293535\n",
+    "mass_dict[\"itraq4KE\"] = 273.14500350000003\n",
+    "mass_dict[\"itraq4KF\"] = 291.1708243\n",
+    "mass_dict[\"itraq4KG\"] = 201.12387413\n",
+    "mass_dict[\"itraq4KH\"] = 281.1613223\n",
+    "mass_dict[\"itraq4KI\"] = 257.1864744\n",
+    "mass_dict[\"itraq4KK\"] = 272.1973734\n",
+    "mass_dict[\"itraq4KL\"] = 257.1864744\n",
+    "mass_dict[\"itraq4KM\"] = 275.142895\n",
+    "mass_dict[\"itraq4KN\"] = 258.1453379\n",
+    "mass_dict[\"itraq4KP\"] = 241.15517426\n",
+    "mass_dict[\"itraq4KQ\"] = 272.1609879\n",
+    "mass_dict[\"itraq4KR\"] = 300.2035214\n",
+    "mass_dict[\"itraq4KS\"] = 231.13443883\n",
+    "mass_dict[\"itraq4KT\"] = 245.15008890000001\n",
+    "mass_dict[\"itraq4KU\"] = 295.0560437957\n",
+    "mass_dict[\"itraq4KV\"] = 243.17082432\n",
+    "mass_dict[\"itraq4KW\"] = 330.1817234\n",
+    "mass_dict[\"itraq4KY\"] = 307.16573900000003\n",
+    "mass_dict[\"itraq4K\"] = 272.1973734\n",
+    "mass_dict[\"itraq4Y\"] = 307.16573900000003\n",
+    "mass_dict[\"itraq8KA\"] = 375.2393133\n",
+    "mass_dict[\"itraq8KC\"] = 407.211384\n",
+    "mass_dict[\"itraq8KD\"] = 419.2291426\n",
+    "mass_dict[\"itraq8KE\"] = 433.2447926\n",
+    "mass_dict[\"itraq8KF\"] = 451.2706134\n",
+    "mass_dict[\"itraq8KG\"] = 361.22366323\n",
+    "mass_dict[\"itraq8KH\"] = 441.2611114\n",
+    "mass_dict[\"itraq8KI\"] = 417.2862635\n",
+    "mass_dict[\"itraq8KK\"] = 432.2971625\n",
+    "mass_dict[\"itraq8KL\"] = 417.2862635\n",
+    "mass_dict[\"itraq8KM\"] = 435.2426841\n",
     "mass_dict[\"itraq8KN\"] = 418.245127\n",
+    "mass_dict[\"itraq8KP\"] = 401.25496336000003\n",
+    "mass_dict[\"itraq8KQ\"] = 432.260777\n",
+    "mass_dict[\"itraq8KR\"] = 460.3033105\n",
+    "mass_dict[\"itraq8KS\"] = 391.23422793\n",
+    "mass_dict[\"itraq8KT\"] = 405.249878\n",
+    "mass_dict[\"itraq8KU\"] = 455.1558328957\n",
+    "mass_dict[\"itraq8KV\"] = 403.27061342\n",
+    "mass_dict[\"itraq8KW\"] = 490.2815125\n",
+    "mass_dict[\"itraq8KY\"] = 467.2655281\n",
     "mass_dict[\"itraq8K\"] = 432.2971625\n",
     "mass_dict[\"itraq8Y\"] = 467.2655281\n",
+    "mass_dict[\"eA\"] = 337.1209813\n",
+    "mass_dict[\"eC\"] = 369.093052\n",
+    "mass_dict[\"eD\"] = 381.1108106\n",
+    "mass_dict[\"eE\"] = 395.1264606\n",
+    "mass_dict[\"eF\"] = 413.1522814\n",
+    "mass_dict[\"eG\"] = 323.10533123\n",
+    "mass_dict[\"eH\"] = 403.1427794\n",
+    "mass_dict[\"eI\"] = 379.1679315\n",
     "mass_dict[\"eK\"] = 394.1788305\n",
+    "mass_dict[\"eL\"] = 379.1679315\n",
+    "mass_dict[\"eM\"] = 397.1243521\n",
+    "mass_dict[\"eN\"] = 380.126795\n",
+    "mass_dict[\"eP\"] = 363.13663136\n",
+    "mass_dict[\"eQ\"] = 394.142445\n",
+    "mass_dict[\"eR\"] = 422.1849785\n",
+    "mass_dict[\"eS\"] = 353.11589592999997\n",
+    "mass_dict[\"eT\"] = 367.131546\n",
+    "mass_dict[\"eU\"] = 417.03750089569996\n",
+    "mass_dict[\"eV\"] = 365.15228142\n",
+    "mass_dict[\"eW\"] = 452.1631805\n",
+    "mass_dict[\"eY\"] = 429.1471961\n",
     "mass_dict[\"arg10R\"] = 166.10938057776002\n",
     "mass_dict[\"arg6R\"] = 162.121241\n",
-    "mass_dict[\"lys8K\"] = 136.10916278887998\n",
-    "\n",
+    "mass_dict[\"lys8K\"] = 136.10916278888\n",
     "mass_dict[\"Electron\"] = 0.00054857990907\n",
     "mass_dict[\"Proton\"] = 1.00727646687\n",
     "mass_dict[\"Hydrogen\"] = 1.00782503223\n",
@@ -151,8 +303,8 @@
     "mass_dict[\"Oxygen\"] = 15.994914619\n",
     "mass_dict[\"OH\"] = 17.002739651229998\n",
     "mass_dict[\"H2O\"] = 18.01056468346\n",
-    "mass_dict[\"NH3\"] = 17.03052\n",
     "\n",
+    "mass_dict[\"NH3\"] = 17.03052\n",
     "mass_dict[\"delta_M\"] = 1.00286864\n",
     "mass_dict[\"delta_S\"] = 0.0109135"
    ]
@@ -166,8 +318,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "71.03711379999999\n",
-      "128.09496299999998\n"
+      "71.0371138\n",
+      "128.094963\n"
      ]
     }
    ],
@@ -225,6 +377,7 @@
     "\n",
     "    mods = pd.read_csv(modfile, delimiter=\"\\t\")\n",
     "    aas = pd.read_csv(aasfile, delimiter=\"\\t\")\n",
+    "    \n",
     "\n",
     "    mass_dict = Dict.empty(key_type=types.unicode_type, value_type=types.float64)\n",
     "\n",
@@ -238,8 +391,8 @@
     "\n",
     "        if (\"<\" in identifier) or (\">\" in identifier):\n",
     "            for aa_identifier, aa_mass in aas[[\"Identifier\", \"Monoisotopic Mass (Da)\"]].values:\n",
-    "                if '^' in aa_identifier:\n",
-    "                    new_identifier = identifier[:-1] + aa_identifier\n",
+    "                if '^' in identifier:\n",
+    "                    new_identifier = identifier[:-2] + aa_identifier\n",
     "                    mass_dict[new_identifier] = float(mass) + mass_dict[aa_identifier]\n",
     "                elif aar == aa_identifier:\n",
     "                    new_identifier = identifier[:-2] + aa_identifier\n",
@@ -441,7 +594,9 @@
     "protease_dict[\"trypsin_full\"] = \"([KR](?=[^P]))|((?<=W)K(?=P))|((?<=M)R(?=P))\"\n",
     "protease_dict[\"trypsin_exception\"] = \"((?<=[CD])K(?=D))|((?<=C)K(?=[HY]))|((?<=C)R(?=K))|((?<=R)R(?=[HR]))\"\n",
     "protease_dict[\"non-specific\"] = \"()\"\n",
-    "protease_dict[\"trypsin\"] = \"([KR](?=[^P]))\""
+    "protease_dict[\"trypsin\"] = \"([KR](?=[^P]))\"\n",
+    "\n",
+    "\n"
    ]
   },
   {
@@ -500,7 +655,8 @@
       "Converted 10_constants.ipynb.\n",
       "Converted 11_interface.ipynb.\n",
       "Converted 12_speed.ipynb.\n",
-      "Converted index.ipynb.\n"
+      "Converted index.ipynb.\n",
+      "Converted Untitled.ipynb.\n"
      ]
     }
    ],
diff --git a/nbs/11_interface.ipynb b/nbs/11_interface.ipynb
index a5a9b0b5..09970886 100644
--- a/nbs/11_interface.ipynb
+++ b/nbs/11_interface.ipynb
@@ -785,7 +785,7 @@
     "                    df['rt_left'] = df['rt_apex'] - df['rt_start']\n",
     "                    df['rt_tail'] = df['rt_right'] / df['rt_left']\n",
     "                \n",
-    "                for field in ['fwhm','int_sum','rt_length','o_mass_ppm_raw']:\n",
+    "                for field in ['fwhm','int_sum','rt_length','rt_tail','o_mass_ppm_raw']:\n",
     "                    if field in df.columns:\n",
     "                        f_summary[key+'_median_'+field] = float(df[field].median())\n",
     "                        \n",
diff --git a/requirements.txt b/requirements.txt
index c2893424..2aee367c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,3 +22,4 @@ click==7.1.2
 streamlit==0.80.0
 plotly_express==0.4.0
 watchdog==2.1.0
+wget==3.2
diff --git a/settings.ini b/settings.ini
index 06845c71..25081a17 100644
--- a/settings.ini
+++ b/settings.ini
@@ -7,7 +7,7 @@ author = Maximilian T. Strauss
 author_email = straussmaximilian@gmail.com
 copyright = Mann Labs
 branch = master
-version = 0.3.21
+version = 0.3.22
 min_python = 3.6
 max_python = 4
 audience = Developers


Test patch:
diff --git a/.github/workflows/performance_test_installer.yml b/.github/workflows/performance_test_installer.yml
index 46d47934..e4c2bb8a 100644
--- a/.github/workflows/performance_test_installer.yml
+++ b/.github/workflows/performance_test_installer.yml
@@ -10,7 +10,18 @@ jobs:
         run: |
           conda deactivate
           cd installer\one_click_windows
-          .\create_pyinstaller_windows.bat
+          .\create_installer_windows.bat
+  Prepare_Environment_for_testing:
+    needs: [Pyinstaller]
+    runs-on: self-hosted
+    steps:
+    - uses: actions/checkout@v2
+    - name: Install package
+      run: |
+        conda activate alphapeptinstaller
+        pip install pymongo
+        pip install dnspython
+        pip install wget
   HeLa_Thermo_Win:
     needs: Pyinstaller
     runs-on: self-hosted
@@ -18,6 +29,7 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on Thermo
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" thermo_hela
   HeLa_Thermo_Win_LargeFasta:
     needs: [Pyinstaller, HeLa_Thermo_Win]
@@ -26,6 +38,7 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on Thermo
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" thermo_hela_large_fasta
   HeLa_Thermo_Win_Modifications:
     needs: [Pyinstaller, HeLa_Thermo_Win]
@@ -34,6 +47,7 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on Thermo
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" thermo_hela_modifications
   HeLa_Bruker_Win:
     needs: [Pyinstaller, HeLa_Thermo_Win]
@@ -42,6 +56,7 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on Bruker
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" bruker_hela
   PXD006109:
     needs: [Pyinstaller, HeLa_Thermo_Win]
@@ -50,6 +65,7 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on PXD006109
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" PXD006109
   PXD010012:
     needs: [Pyinstaller, HeLa_Bruker_Win]
@@ -58,4 +74,5 @@ jobs:
     - uses: actions/checkout@v2
     - name: Run Alphapept on PXD010012
       run: |
+        conda activate alphapeptinstaller
         python test_ci.py "${{ secrets.MONGODB_PW }}" PXD010012
diff --git a/test_ci.py b/test_ci.py
index a0985318..9d6e3305 100644
--- a/test_ci.py
+++ b/test_ci.py
@@ -85,8 +85,6 @@ def __init__(self, id, experimental_files, fasta_paths, new_files, custom_settin
         self.id = id
         self.file_paths = experimental_files
         self.fasta_paths = fasta_paths
-        self.m_tol = 20
-        self.m_offset = 20
         self.new_files = new_files
 
         self.custom_settings = custom_settings
@@ -151,9 +149,6 @@ def prepare_settings(self):
         self.settings['experiment']['file_paths'] =  [TEST_DIR + _ for _ in self.file_paths]
         self.settings['experiment']['fasta_paths'] = [TEST_DIR + _ for _ in self.fasta_paths]
 
-        self.settings['search']['m_offset'] =  self.m_offset
-        self.settings['search']['m_tol'] =  self.m_tol
-
     def run(self, password=None):
         if self.new_files:
             self.prepare_files()