# HG changeset patch
# User galaxyp
# Date 1669921016 0
# Node ID 016964c597f50d16facc8d3f7fbc9c921fbf12ad
# Parent 0fc9ae55bcfcc316b622dbe32e75f59436669f4b
planemo upload for repository https://github.com/galaxyproteomics/tools-galaxyp/tree/master/tools/openms commit 3d1e5f37fd16524a415f707772eeb7ead848c5e3
diff -r 0fc9ae55bcfc -r 016964c597f5 404-urls.patch
--- a/404-urls.patch Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-diff -ruN FeatureFinderSuperHirn.xml FeatureFinderSuperHirn.xml
---- FeatureFinderSuperHirn.xml 2020-10-02 12:06:56.398572301 +0200
-+++ FeatureFinderSuperHirn.xml 2020-10-02 12:07:31.511153834 +0200
-@@ -105,6 +105,6 @@
-
-+For more information, visit https://abibuilder.informatik.uni-tuebingen.de/archive/openms/Documentation/release/2.6.0/html/UTILS_FeatureFinderSuperHirn.html]]>
-
-
diff -r 0fc9ae55bcfc -r 016964c597f5 OMSSAAdapter.patch
--- a/OMSSAAdapter.patch Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
---- OMSSAAdapter.xml 2020-06-16 15:51:40.315400730 +0200
-+++ /tmp/OMSSAAdapter.xml 2020-06-16 15:50:23.536086074 +0200
-@@ -22,6 +22,7 @@
- mkdir database &&
- ln -s '$database' 'database/${re.sub("[^\w\-_]", "_", $database.element_identifier)}.$gxy2omsext($database.ext)' &&
-
-+makeblastdb -dbtype prot -in 'database/${re.sub("[^\w\-_]", "_", $database.element_identifier)}.$gxy2omsext($database.ext)' &&
- ## Main program call
-
- set -o pipefail &&
diff -r 0fc9ae55bcfc -r 016964c597f5 PepNovoAdapter.patch
--- a/PepNovoAdapter.patch Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
---- PepNovoAdapter.xml 2020-05-12 15:55:24.712831518 +0200
-+++ /tmp/PepNovoAdapter.xml 2020-05-12 15:36:31.267276757 +0200
-@@ -42,8 +42,13 @@
-
-
-
--
--
-+
-+
-+
-+
-+
-+
-+
-
-
-
-@@ -51,8 +56,14 @@
-
-
-
--
--
-+
-+
-+
-+
-+
-+
-+
-+
-
-
-
diff -r 0fc9ae55bcfc -r 016964c597f5 PercolatorAdapter.xml
--- a/PercolatorAdapter.xml Fri Nov 06 20:36:48 2020 +0000
+++ b/PercolatorAdapter.xml Thu Dec 01 18:56:56 2022 +0000
@@ -1,13 +1,11 @@
-
+
Facilitate input to Percolator and reintegrate.
PercolatorAdapter
macros.xml
- macros_autotest.xml
- macros_test.xml
@@ -16,13 +14,23 @@
#import re
## Preprocessing
-#if $in:
- mkdir in &&
- ${ ' '.join(["ln -s '%s' 'in/%s.%s' &&" % (_, re.sub('[^\w\-_]', '_', _.element_identifier), $gxy2omsext(_.ext)) for _ in $in if _]) }
+#if $in_cond.in:
+ mkdir in_cond.in &&
+ #if $in_cond.in_select == "no"
+ mkdir ${' '.join(["'in_cond.in/%s'" % (i) for i, f in enumerate($in_cond.in) if f])} &&
+ ${' '.join(["ln -s '%s' 'in_cond.in/%s/%s.%s' && " % (f, i, re.sub('[^\w\-_]', '_', f.element_identifier), $gxy2omsext(f.ext)) for i, f in enumerate($in_cond.in) if f])}
+ #else
+ ln -s '$in_cond.in' 'in_cond.in/${re.sub("[^\w\-_]", "_", $in_cond.in.element_identifier)}.$gxy2omsext($in_cond.in.ext)' &&
+ #end if
#end if
-#if $in_decoy:
- mkdir in_decoy &&
- ${ ' '.join(["ln -s '%s' 'in_decoy/%s.%s' &&" % (_, re.sub('[^\w\-_]', '_', _.element_identifier), $gxy2omsext(_.ext)) for _ in $in_decoy if _]) }
+#if $in_decoy_cond.in_decoy:
+ mkdir in_decoy_cond.in_decoy &&
+ #if $in_decoy_cond.in_decoy_select == "no"
+ mkdir ${' '.join(["'in_decoy_cond.in_decoy/%s'" % (i) for i, f in enumerate($in_decoy_cond.in_decoy) if f])} &&
+ ${' '.join(["ln -s '%s' 'in_decoy_cond.in_decoy/%s/%s.%s' && " % (f, i, re.sub('[^\w\-_]', '_', f.element_identifier), $gxy2omsext(f.ext)) for i, f in enumerate($in_decoy_cond.in_decoy) if f])}
+ #else
+ ln -s '$in_decoy_cond.in_decoy' 'in_decoy_cond.in_decoy/${re.sub("[^\w\-_]", "_", $in_decoy_cond.in_decoy.element_identifier)}.$gxy2omsext($in_decoy_cond.in_decoy.ext)' &&
+ #end if
#end if
#if $in_osw:
mkdir in_osw &&
@@ -47,16 +55,14 @@
#if "weights_FLAG" in str($OPTIONAL_OUTPUTS).split(',')
mkdir weights &&
#end if
-#if $adv_opts_cond.adv_opts_selector=='advanced':
- #if $adv_opts_cond.init_weights:
- mkdir adv_opts_cond.init_weights &&
- ln -s '$adv_opts_cond.init_weights' 'adv_opts_cond.init_weights/${re.sub("[^\w\-_]", "_", $adv_opts_cond.init_weights.element_identifier)}.$gxy2omsext($adv_opts_cond.init_weights.ext)' &&
+ #if $adv_opts.init_weights:
+ mkdir adv_opts.init_weights &&
+ ln -s '$adv_opts.init_weights' 'adv_opts.init_weights/${re.sub("[^\w\-_]", "_", $adv_opts.init_weights.element_identifier)}.$gxy2omsext($adv_opts.init_weights.ext)' &&
#end if
- #if $adv_opts_cond.fasta:
- mkdir adv_opts_cond.fasta &&
- ln -s '$adv_opts_cond.fasta' 'adv_opts_cond.fasta/${re.sub("[^\w\-_]", "_", $adv_opts_cond.fasta.element_identifier)}.$gxy2omsext($adv_opts_cond.fasta.ext)' &&
+ #if $adv_opts.fasta:
+ mkdir adv_opts.fasta &&
+ ln -s '$adv_opts.fasta' 'adv_opts.fasta/${re.sub("[^\w\-_]", "_", $adv_opts.fasta.element_identifier)}.$gxy2omsext($adv_opts.fasta.ext)' &&
#end if
-#end if
## Main program call
@@ -64,13 +70,21 @@
@EXECUTABLE@ -write_ctd ./ &&
python3 '$__tool_directory__/fill_ctd.py' '@EXECUTABLE@.ctd' '$args_json' '$hardcoded_json' &&
@EXECUTABLE@ -ini @EXECUTABLE@.ctd
-#if $in:
+#if $in_cond.in:
-in
- ${' '.join(["'in/%s.%s'"%(re.sub('[^\w\-_]', '_', _.element_identifier), $gxy2omsext(_.ext)) for _ in $in if _])}
+ #if $in_cond.in_select == "no"
+ ${' '.join(["'in_cond.in/%s/%s.%s'"%(i, re.sub('[^\w\-_]', '_', f.element_identifier), $gxy2omsext(f.ext)) for i, f in enumerate($in_cond.in) if f])}
+ #else
+ 'in_cond.in/${re.sub("[^\w\-_]", "_", $in_cond.in.element_identifier)}.$gxy2omsext($in_cond.in.ext)'
+ #end if
#end if
-#if $in_decoy:
+#if $in_decoy_cond.in_decoy:
-in_decoy
- ${' '.join(["'in_decoy/%s.%s'"%(re.sub('[^\w\-_]', '_', _.element_identifier), $gxy2omsext(_.ext)) for _ in $in_decoy if _])}
+ #if $in_decoy_cond.in_decoy_select == "no"
+ ${' '.join(["'in_decoy_cond.in_decoy/%s/%s.%s'"%(i, re.sub('[^\w\-_]', '_', f.element_identifier), $gxy2omsext(f.ext)) for i, f in enumerate($in_decoy_cond.in_decoy) if f])}
+ #else
+ 'in_decoy_cond.in_decoy/${re.sub("[^\w\-_]", "_", $in_decoy_cond.in_decoy.element_identifier)}.$gxy2omsext($in_decoy_cond.in_decoy.ext)'
+ #end if
#end if
#if $in_osw:
-in_osw
@@ -102,16 +116,14 @@
-weights
'weights/output.${gxy2omsext("tabular")}'
#end if
-#if $adv_opts_cond.adv_opts_selector=='advanced':
- #if $adv_opts_cond.init_weights:
+ #if $adv_opts.init_weights:
-init_weights
- 'adv_opts_cond.init_weights/${re.sub("[^\w\-_]", "_", $adv_opts_cond.init_weights.element_identifier)}.$gxy2omsext($adv_opts_cond.init_weights.ext)'
+ 'adv_opts.init_weights/${re.sub("[^\w\-_]", "_", $adv_opts.init_weights.element_identifier)}.$gxy2omsext($adv_opts.init_weights.ext)'
#end if
- #if $adv_opts_cond.fasta:
+ #if $adv_opts.fasta:
-fasta
- 'adv_opts_cond.fasta/${re.sub("[^\w\-_]", "_", $adv_opts_cond.fasta.element_identifier)}.$gxy2omsext($adv_opts_cond.fasta.ext)'
+ 'adv_opts.fasta/${re.sub("[^\w\-_]", "_", $adv_opts.fasta.element_identifier)}.$gxy2omsext($adv_opts.fasta.ext)'
#end if
-#end if
#if len(str($OPTIONAL_OUTPUTS).split(',')) == 0
| tee '$stdout'
#end if
@@ -144,16 +156,38 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -167,53 +201,56 @@
-
+
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
@@ -227,9 +264,8 @@
-
+
-
@@ -256,13 +292,240 @@
OPTIONAL_OUTPUTS is not None and "ctd_out_FLAG" in OPTIONAL_OUTPUTS
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+For more information, visit http://www.openms.de/doxygen/release/2.8.0/html/TOPP_PercolatorAdapter.html]]>
diff -r 0fc9ae55bcfc -r 016964c597f5 filetypes.txt
--- a/filetypes.txt Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-# CTD type # Galaxy type
-# the following lines need to be at the top in order to ensure
-# correct translation Galaxy->CTD type for the ambiguous cases
-# (should only be relevant for the autogenerated tests [which
-# do not set the ftype of the inputs])
-txt txt
-tsv tabular
-
-##analysisXML
-# XTandemAdapter output is named xml in OMS (which is to unspecific) and bioml in Galaxy .. so this is renamed via hardcoded parameters
-bioml xml
-consensusXML consensusxml
-# TODO csv is problematic, since csv often actually means tsv .. but not always
-csv csv
-##dat
-dta dta
-dta2d dta2d
-edta edta
-fa fasta
-fas fasta
-fasta fasta
-FASTA fasta
-featureXML featurexml
-featurexml featurexml
-# fid
-html html
-HTML html
-idXML idxml
-##ini txt
-json json
-kroenik kroenik
-mascotXML mascotxml
-mgf mgf
-mrm mrm
-ms sirius.ms
-ms2 ms2
-msp msp
-mzData mzdata
-mzid mzid
-# important to have mzML first, since LuciphorAdapter is case sensitive https://github.com/OpenMS/OpenMS/issues/4444
-mzML mzml
-mzml mzml
-mzq mzq
-mzTab mztab
-mzXML mzxml
-novor txt
-obo obo
-# I guess this is the idXML output of omssa
-omssaXML idxml
-osw osw
-OSW osw
-params txt
-paramXML paramxml
-fasta peff
-peplist peplist
-# TODO pep.xml should be removed with OMS 2.6 https://github.com/OpenMS/OpenMS/pull/4541 .. but still in the tests
-pep.xml pepxml
-pepXML pepxml
-png png
-PNG png
-protXML protxml
-psms psms
-# TODO implement or use
-# psq
-pqp pqp
-qcML qcml
-spec.xml spec.xml
-splib splib
-sqMass sqmass
-tandem.xml tandem
-trafoXML trafoxml
-traML traml
-TraML traml
-tab tabular
-## MOVED TO TOP txt txt
-raw thermo.raw
-## xls: SpectraSTSearchAdapter https://github.com/OpenMS/OpenMS/pull/4419
-xls tsv
-XML xml
-xml xml
-xquest.xml xquest.xml
-xsd xml
-
-# TODO needs to be implemented, needs to be below xml in order that Galaxy->OMS mapping gives xml
-# cachedMzML xml
diff -r 0fc9ae55bcfc -r 016964c597f5 fill_ctd.py
--- a/fill_ctd.py Fri Nov 06 20:36:48 2020 +0000
+++ b/fill_ctd.py Thu Dec 01 18:56:56 2022 +0000
@@ -32,7 +32,7 @@
for k, v in e.items():
if (k in d and isinstance(d[k], dict) and isinstance(e[k], collections.abc.Mapping)):
mergeDicts(d[k], e[k])
- elif k not in d and not isinstance(e[k], collections.abc.Mapping):
+ elif k not in d:
d[k] = e[k]
else:
sys.stderr.write("fill_ctd.py: could not merge key %s for %s in %s" % (k, d, e))
@@ -135,9 +135,10 @@
# insert the hc_args into the args
mergeDicts(args, hc_args)
-if "adv_opts_cond" in args:
- args.update(args["adv_opts_cond"])
- del args["adv_opts_cond"]
+# put the contents of the advanced options section into the main dict
+if "adv_opts" in args:
+ args.update(args["adv_opts"])
+ del args["adv_opts"]
# IDMapper has in and spectra:in params, in is used in out as format_source",
# which does not work in Galaxy: https://github.com/galaxyproject/galaxy/pull/9493"
diff -r 0fc9ae55bcfc -r 016964c597f5 fill_ctd_clargs.py
--- a/fill_ctd_clargs.py Fri Nov 06 20:36:48 2020 +0000
+++ b/fill_ctd_clargs.py Thu Dec 01 18:56:56 2022 +0000
@@ -1,40 +1,70 @@
#!/usr/bin/env python3
+
+import operator
from argparse import ArgumentParser
+from functools import reduce # forward compatibility for Python 3
from io import StringIO
from CTDopts.CTDopts import (
+ _Null,
CTDModel,
ModelTypeError,
Parameters
)
+
+def getFromDict(dataDict, mapList):
+ return reduce(operator.getitem, mapList, dataDict)
+
+
+def setInDict(dataDict, mapList, value):
+ getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value
+
+
if __name__ == "__main__":
# note add_help=False since otherwise arguments starting with -h will
# trigger an error (despite allow_abbreviate)
parser = ArgumentParser(prog="fill_ctd_clargs",
description="fill command line arguments"
- "into a CTD file and write the CTD file to",
+ "into a CTD file and write the CTD file to stdout",
add_help=False, allow_abbrev=False)
- parser.add_argument("--ctd", dest="ctd", help="input ctd file",
- metavar='CTD', default=None, required=True)
+ parser.add_argument("--ini_file", dest="ini_file", help="input ini file",
+ metavar='INI', default=None, required=True)
+ parser.add_argument("--ctd_file", dest="ctd_file", help="input ctd file"
+ "if given then optional parameters from the ini file"
+ "will be filled with the defaults from this CTD file",
+ metavar='CTD', default=None, required=False)
args, cliargs = parser.parse_known_args()
+
# load CTDModel
- model = None
+ ini_model = None
try:
- model = CTDModel(from_file=args.ctd)
+ ini_model = CTDModel(from_file=args.ini_file)
except ModelTypeError:
pass
try:
- model = Parameters(from_file=args.ctd)
+ ini_model = Parameters(from_file=args.ini_file)
except ModelTypeError:
pass
- assert model is not None, "Could not parse %s, seems to be no CTD/PARAMS" % (args.ctd)
+ assert ini_model is not None, "Could not parse %s, seems to be no CTD/PARAMS" % (args.ini_file)
# get a dictionary of the ctd arguments where the values of the parameters
# given on the command line are overwritten
- margs = model.parse_cl_args(cl_args=cliargs, ignore_required=True)
+ ini_values = ini_model.parse_cl_args(cl_args=cliargs, ignore_required=True)
+
+ if args.ctd_file:
+ ctd_model = CTDModel(from_file=args.ctd_file)
+ ctd_values = ctd_model.get_defaults()
+ for param in ini_model.get_parameters():
+ if not param.required and (param.default is None or type(param.default) is _Null):
+ lineage = param.get_lineage(name_only=True)
+ try:
+ default = getFromDict(ctd_values, lineage)
+ except KeyError:
+ continue
+ setInDict(ini_values, lineage, default)
# write the ctd with the values taken from the dictionary
out = StringIO()
- ctd_tree = model.write_ctd(out, margs)
+ ctd_tree = ini_model.write_ctd(out, ini_values)
print(out.getvalue())
diff -r 0fc9ae55bcfc -r 016964c597f5 generate-foo.sh
--- a/generate-foo.sh Fri Nov 06 20:36:48 2020 +0000
+++ b/generate-foo.sh Thu Dec 01 18:56:56 2022 +0000
@@ -8,17 +8,15 @@
# get the tests from the CMakeLists.txt
# 1st remove some tests
- # - OpenSwathMzMLFileCacher with -convert_back argumen https://github.com/OpenMS/OpenMS/issues/4399
+ # - OpenSwathMzMLFileCacher with -convert_back argument https://github.com/OpenMS/OpenMS/issues/4399
# - IDRipper PATH gets empty causing problems. TODO But overall the option needs to be handled differentlt
# - several tools with duplicated input (leads to conflict when linking)
- # - TOFCalibration inputs we extension (also in prepare_test_data) https://github.com/OpenMS/OpenMS/pull/4525
# - MaRaCluster with -consensus_out (parameter blacklister: https://github.com/OpenMS/OpenMS/issues/4456)
# - FileMerger with mixed dta dta2d input (ftype can not be specified in the test, dta can not be sniffed)
# - some input files are originally in a subdir (degenerated cases/), but not in test-data
- # - SeedListGenerator: https://github.com/OpenMS/OpenMS/issues/4404
# - OpenSwathAnalyzer 9/10: cachedMzML (not supported yet)
- # - FeatureFinderIdentification name clash of two tests https://github.com/OpenMS/OpenMS/pull/5002
- # - TODO SiriusAdapter https://github.com/OpenMS/OpenMS/pull/5010
+ # - SiriusAdapter_4 depends on online service which may timeout .. so keep disabled https://github.com/OpenMS/OpenMS/pull/5010
+ # - SiriusAdapter_10 should work in >2.8 https://github.com/OpenMS/OpenMS/issues/5869
CMAKE=$(cat $OPENMSGIT/src/tests/topp/CMakeLists.txt $OPENMSGIT/src/tests/topp/THIRDPARTY/third_party_tests.cmake |
sed 's@${DATA_DIR_SHARE}/@@g' |
grep -v 'OpenSwathMzMLFileCacher .*-convert_back' |
@@ -26,19 +24,9 @@
grep -v "MaRaClusterAdapter.*-consensus_out"|
grep -v "FileMerger_1_input1.dta2d.*FileMerger_1_input2.dta " |
sed 's@degenerate_cases/@@g' |
- grep -v 'TOPP_SeedListGenerator_3"' |
egrep -v 'TOPP_OpenSwathAnalyzer_test_3"|TOPP_OpenSwathAnalyzer_test_4"' |
- egrep -v '"TOPP_FeatureFinderIdentification_4"' |
- sed 's/\("TOPP_SiriusAdapter_4".*\)-sirius:database all\(.*\)/\1-sirius:database pubchem\2/')
-
-
-# grep -v 'FileFilter.*-spectra:select_polarity ""' |
-# grep -v 'MassTraceExtractor_2.ini ' |
-# grep -v "FileMerger_6_input2.mzML.*FileMerger_6_input2.mzML" |
-# grep -v "IDMerger_1_input1.idXML.*IDMerger_1_input1.idXML" |
-# grep -v "degenerated_empty.idXML.*degenerated_empty.idXML" |
-# grep -v "FeatureLinkerUnlabeledKD_1_output.consensusXML.*FeatureLinkerUnlabeledKD_1_output.consensusXML" |
-# grep -v "FeatureLinkerUnlabeledQT_1_output.consensusXML.*FeatureLinkerUnlabeledQT_1_output.consensusXML" |
+ sed 's/\("TOPP_SiriusAdapter_4".*\)-sirius:database all\(.*\)/\1-sirius:database pubchem\2/' |
+ grep -v '"TOPP_SiriusAdapter_10"')
# 1st part is a dirty hack to join lines containing a single function call, e.g.
# addtest(....
@@ -50,6 +38,7 @@
# >&2 echo $line
test_id=$(echo "$line" | cut -d" " -f 1)
tool_id=$(echo "$line" | cut -d" " -f 2)
+ # >&2 echo "test_id $test_id"
if [[ $test_id =~ _out_?[0-9]? ]]; then
>&2 echo " skip $test_id $line"
continue
@@ -67,7 +56,7 @@
tes=" \n"
line=$(fix_tmp_files "$line")
line=$(unique_files "$line")
- # >&2 echo $line
+ # >&2 echo LINE $line
#if there is an ini file then we use this to generate the test
#otherwise the ctd file is used
#other command line parameters are inserted later into this xml
@@ -77,19 +66,23 @@
else
ini="ctd/$tool_id.ctd"
fi
+ # >&2 echo "========================================================"
+ # >&2 echo "USING ini $ini"
cli=$(echo $line |cut -d" " -f3- | sed 's/-ini [^ ]\+//')
ctdtmp=$(mktemp)
- #echo python3 fill_ctd_clargs.py --ctd $ini $cli
# using eval: otherwise for some reason quoted values are not used properly ('A B' -> ["'A", "B'"])
- # >&2 echo "python3 fill_ctd_clargs.py --ctd $ini $cli"
- eval "python3 fill_ctd_clargs.py --ctd $ini $cli" > "$ctdtmp"
- # echo $ctdtmp
+ # >&2 echo "python3 fill_ctd_clargs.py --ini_file $ini $cli"
+ eval "python3 fill_ctd_clargs.py --ini_file $ini $cli" > "$ctdtmp"
+ # >&2 echo $ctdtmp
# >&2 cat $ctdtmp
testtmp=$(mktemp)
- python3 $CTDCONVERTER/convert.py galaxy -i $ctdtmp -o $testtmp -s tools_blacklist.txt -f "$FILETYPES" -m macros.xml -t tool.conf -p hardcoded_params.json --tool-version $VERSION --test-only --test-unsniffable csv tsv txt dta dta2d edta mrm splib > /dev/null
+ # >&2 echo CTDConverter galaxy -i $ctdtmp -o $testtmp -s aux/tools_blacklist.txt -f "$FILETYPES" -m macros.xml -t tool.conf -p aux/hardcoded_params.json --tool-version $VERSION --test-only --test-unsniffable csv tsv txt dta dta2d edta mrm splib --test-condition "compare=sim_size" "delta_frac=0.7"
+ CTDConverter galaxy -i $ctdtmp -o $testtmp -s aux/tools_blacklist.txt -f "$FILETYPES" -m macros.xml -t tool.conf -p aux/hardcoded_params.json --tool-version $VERSION --test-only --test-unsniffable csv tsv txt dta dta2d edta mrm splib --test-condition "compare=sim_size" "delta_frac=0.7" > /dev/null
+ echo ""
cat $testtmp | grep -v ' /dev/null
@@ -130,23 +123,23 @@
#(e.g. for prepare_test_data, e.g. CLI expects csv but test file is txt)
#this function replaces the tmp file by the expected file.
function fix_tmp_files {
-# >&2 echo "FIX $line"
+ # >&2 echo "FIX $line"
ret=""
for a in $@; do
- if [[ ! $a =~ .tmp$ ]]; then
+ # >&2 echo " a "$a
+ if [[ ! $a =~ .tmp$ ]] && [[ ! $a =~ _tmp_ ]]; then
ret="$ret $a"
continue
fi
-# >&2 echo " a "$a
- g=$(cat $OPENMSGIT/src/tests/topp/CMakeLists.txt $OPENMSGIT/src/tests/topp/THIRDPARTY/third_party_tests.cmake | awk '{printf("%s@NEWLINE@", $0)}' | sed 's/)@NEWLINE@/)\n/g' | sed 's/@NEWLINE@/ /g' | grep '\${DIFF}.*'"$a")
-# >&2 echo " g "$g
- in1=$(sed 's/.*-in1 \([^ ]\+\).*/\1/' <<<$g)
+ diff_line=$(cat $OPENMSGIT/src/tests/topp/CMakeLists.txt $OPENMSGIT/src/tests/topp/THIRDPARTY/third_party_tests.cmake | awk '{printf("%s@NEWLINE@", $0)}' | sed 's/)@NEWLINE@/)\n/g' | sed 's/@NEWLINE@/ /g' | grep '\${DIFF}.*'"$a")
+ # >&2 echo " diff_line "$diff_line
+ in1=$(sed 's/.*-in1 \([^ ]\+\).*/\1/' <<<$diff_line)
# >&2 echo " in1 "$in1
if [[ "$a" != "$in1" ]]; then
ret="$ret $a"
continue
fi
- in2=$(sed 's/.*-in2 \([^ ]\+\).*/\1/' <<<$g)
+ in2=$(sed 's/.*-in2 \([^ ]\+\).*/\1/' <<<$diff_line)
in2=$(basename $in2 | sed 's/)$//')
# >&2 echo " in2 "$in2
if [[ -f "test-data/$in2" ]]; then
@@ -176,11 +169,11 @@
fi
ln -f -s $in1 test-data/$in2
done
- for i in test-data/*.tmp
- do
+
+ find test-data/ -name "*.tmp" -print0 |
+ while IFS= read -r -d '' i; do
if [ ! -e test-data/$(basename $i .tmp) ]; then
ln -s $(basename $i) test-data/$(basename $i .tmp)
- #ln -s $(basename $i) test-data/$(basename $i .tmp)
else
ln -fs $(basename $i) test-data/$(basename $i .tmp)
fi
@@ -194,14 +187,14 @@
# id=$1
# | egrep -i "$id\_.*[0-9]+(_prepare\"|_convert)?"
-# TODO SiriusAdapter https://github.com/OpenMS/OpenMS/pull/5010
+ # TODO SiriusAdapter depends on online service which may timeout .. so keep disabled https://github.com/OpenMS/OpenMS/pull/5010
cat $OPENMSGIT/src/tests/topp/CMakeLists.txt $OPENMSGIT/src/tests/topp/THIRDPARTY/third_party_tests.cmake | sed 's/#.*$//'| sed 's/^\s*//; s/\s*$//' | grep -v "^$" | awk '{printf("%s@NEWLINE@", $0)}' | sed 's/)@NEWLINE@/)\n/g' | sed 's/@NEWLINE@/ /g' |
sed 's/degenerate_cases\///' |
egrep -v "WRITEINI|WRITECTD|INVALIDVALUE|DIFF" |
grep add_test |
egrep "TOPP|UTILS" |
sed 's@${DATA_DIR_SHARE}/@@g;'|
- sed 's@${TMP_RIP_PATH}@dummy2.tmp@g'|
+ sed 's@${TMP_RIP_PATH}@./@g'|
sed 's@TOFCalibration_ref_masses @TOFCalibration_ref_masses.txt @g; s@TOFCalibration_const @TOFCalibration_const.csv @'|
sed 's/\("TOPP_SiriusAdapter_4".*\)-sirius:database all\(.*\)/\1-sirius:database pubchem\2/' |
while read line
diff -r 0fc9ae55bcfc -r 016964c597f5 generate.sh
--- a/generate.sh Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#!/usr/bin/env bash
-
-VERSION=2.6
-FILETYPES="filetypes.txt"
-PROFILE="20.05"
-## FILETYPES_RE=$(grep -v "^#" $FILETYPES | grep -v "^$" | cut -f 1 -d" " | tr '\n' '|' | sed 's/|$//'| sed 's/|/\\|/g')
-
-export tmp=$(mktemp -d)
-export CTDCONVERTER="$tmp/CTDConverter"
-
-###############################################################################
-## reset old data
-###############################################################################
-# rm $(ls *xml |grep -v macros)
-# rm -rf ctd
-# mkdir -p ctd
-# echo "" > prepare_test_data.sh
-
-###############################################################################
-## generate tests
-## also creates
-## - conda environment (for executing the binaries) and
-## - the git clone of OpenMS (for generating the tests)
-## - ctd files
-###############################################################################
-bash ./test-data.sh ./macros_autotest.xml
-
-###############################################################################
-## get the
-## - conda package (for easy access and listing of the OpenMS binaries),
-###############################################################################
-# if [ ! -d $OPENMSPKG ]; then
-# mkdir $OPENMSPKG/
-# wget -P $OPENMSPKG/ "$CONDAPKG"
-# tar -xf $OPENMSPKG/"$(basename $CONDAPKG)" -C OpenMS$VERSION-pkg/
-# rm $OPENMSPKG/"$(basename $CONDAPKG)"
-# fi
-
-###############################################################################
-## Get python libaries for CTD -> Galaxy conversion
-## TODO fix to main repo OR conda packkage if PRs are merged
-###############################################################################
-# if [ ! -d CTDopts ]; then
-# # git clone https://github.com/genericworkflownodes/CTDopts CTDopts
-# git clone -b topic/no-1-2x https://github.com/bernt-matthias/CTDopts CTDopts
-# fi
-if [ ! -d $CTDCONVERTER ]; then
- #git clone https://github.com/WorkflowConversion/CTDConverter.git CTDConverter
- git clone -b topic/cdata https://github.com/bernt-matthias/CTDConverter.git $CTDCONVERTER
-fi
-# export PYTHONPATH=$(pwd)/CTDopts
-###############################################################################
-## conversion ctd->xml
-###############################################################################
-
-find . -maxdepth 0 -name "[A-Z]*xml" -delete
-source $(dirname $(which conda))/../etc/profile.d/conda.sh
-conda activate $tmp/OpenMS$VERSION-env
-python $CTDCONVERTER/convert.py galaxy -i ctd/*ctd -o ./ -s tools_blacklist.txt -f "$FILETYPES" -m macros.xml -t tool.conf -p hardcoded_params.json --test-macros macros_autotest.xml --test-macros-prefix autotest_ --test-macros macros_test.xml --test-macros-prefix manutest_ --tool-version $VERSION --tool-profile $PROFILE > convert.out 2> convert.err
-if [[ "$?" -ne "0" ]]; then >&2 echo 'CTD -> XML conversion failed'; >&2 echo -e "stderr:\n$(cat convert.err)"; fi
-conda deactivate
-
-patch PepNovoAdapter.xml < PepNovoAdapter.patch
-patch OMSSAAdapter.xml < OMSSAAdapter.patch
-
-# https://github.com/OpenMS/OpenMS/pull/4984
-sed -i -e 's@http://www.openms.de/documentation/@http://www.openms.de/doxygen/release/2.6.0/html/@' ./*xml
-# https://github.com/OpenMS/OpenMS/pull/4984#issuecomment-702641976
-patch -p0 <404-urls.patch
-
-# #-b version log debug test in_type executable pepnovo_executable param_model_directory rt_concat_trafo_out param_id_pool
-
-# for i in A-E F-H I-L M-N O-P Q-Z
-# do
-# planemo t [$i]*xml --galaxy_branch release_20.05 --galaxy_python_version 3.7 --test_output $i.html --test_output_json $i.json &
-# done
diff -r 0fc9ae55bcfc -r 016964c597f5 hardcoded_params.json
--- a/hardcoded_params.json Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-{
- "#": "blacklist parameters",
-
- "version": [{"value": "@"}],
- "debug": [{"value": "@"}],
- "algorithm:debug": [{"value": "@"}],
- "java_memory": [{"value": "@"}],
- "java_permgen": [{"value": "@"}],
- "#": "type of input is always determined from the file extension ",
- "in_type": [{"value": "@"}],
-
- "#": "tool specific blacklist parameters",
-
- "convert_back": [{"value": "@", "tools": ["OpenSwathMzMLFileCacher"]}],
- "NET_executable": [{
- "value": "@",
- "tools": ["FileConverter"]
- }],
-
-
- "params_file": [{"value": "@", "tools": ["SpectraSTSearchAdapter"]}],
-
- "#": "TODO not usable in 2.5 https://github.com/OpenMS/OpenMS/issues/4456, corresponding test currently disabled",
- "consensus_out": [{"value": "@", "tools": ["MaRaClusterAdapter"]}],
- "#": "TODO would need treatment as prefix-output",
- "output_directory": [{"value": "@", "tools": ["MaRaClusterAdapter"]}],
-
- "#": "hardcode parameter values",
-
- "comet_version": [{
- "value":"2016.01 rev. 3"
- }],
- "comet_executable": [{
- "value":"comet"
- }],
- "crux_executable": [{
- "value": "crux"
- }],
- "fido_executable": [{
- "value":"Fido"
- }],
- "fidocp_executable": [{
- "value":"FidoChooseParameters"
- }],
- "maracluster_executable": [{
- "value":"/home/berntm/projects/tools-galaxyp/tools/openms/OpenMS2.5.0-git/THIRDPARTY/Linux/64bit/MaRaCluster/maracluster"
- }],
- "mascot_directory": [{
- "value":"TODO"
- }],
- "myrimatch_executable": [{
- "value":"myrimatch"
- }],
- "omssa_executable": [{
- "value":"$(dirname $(realpath $(which omssacl)))/omssacl"
- }],
- "ThermoRaw_executable": [{
- "value": "ThermoRawFileParser.exe",
- "tools": ["FileConverter"]
- }],
- "pepnovo_executable": [{
- "value":"pepnovo"
- }],
- "percolator_executable": [{
- "value":"percolator"
- }],
- "xtandem_executable": [{
- "value":"xtandem"
- }],
- "executable": [
- {
- "value":"$(dirname $(realpath $(which luciphor2)))/luciphor2.jar",
- "tools": ["LuciphorAdapter"]
- }, {
- "value":"/home/berntm/Downloads/MSFragger-20171106/MSFragger-20171106.jar",
- "tools": ["MSFraggerAdapter"]
- }, {
- "value":"$(msgf_plus -get_jar_path)",
- "tools": ["MSGFPlusAdapter"]
- }, {
- "value": "/home/berntm/Downloads/novor/lib/novor.jar",
- "tools": ["NovorAdapter"]
- }, {
- "value":"$(which sirius)",
- "tools": ["SiriusAdapter", "AssayGeneratorMetabo"]
- }, {
- "value":"spectrast",
- "tools": ["SpectraSTSearchAdapter"]
- }
- ],
- "r_executable": [{
- "value":"R"
- }],
- "rscript_executable": [{
- "value":"Rscript"
- }],
- "java_executable": [{
- "value":"java"
- }],
- "log": [{
- "value":"log.txt"
- }],
- "tempDirectory": [{
- "value":"$TMP_DIR"
- }],
- "temp_data_directory": [{
- "value":"$TMP_DIR"
- }],
- "algorithm:Preprocessing:tmp_dir": [{
- "value":"$TMP_DIR"
- }],
- "no_progress": [{
- "value": true
- }],
- "#": "only used in LuciphorAdapter at the moment, inconsistency will be fixed",
- "num_threads": [{
- "value":"${GALAXY_SLOTS:-1}"
- }],
- "threads": [{
- "value": "${GALAXY_SLOTS:-1}"
- }],
- "sirius:cores": [{
- "value": "${GALAXY_SLOTS:-1}"
- }],
-
- "#": "hardcode the outer loop threads for OpenSwathWorkflow",
- "outer_loop_threads": [{
- "value": "1",
- "tools": ["OpenSwathWorkflow"]
- }],
- "separator": [{
- "value": ",",
- "tools": ["IDMassAccuracy"]
- }],
-
- "#": "don't alow to copy data internally to save computation time for reloading",
- "copy_data": [{
- "value": "false",
- "tools": ["MapAlignerTreeGuided"]
- }],
-
- "#": "overwrite/add Galaxy xml attributes of some parameters (names need to start with param_)",
-
- "#": "test is not a hardcoded value since we need to set it in the tool tests",
- "test": [{
- "CTD:type": "text",
- "XML:type": "hidden"
- }],
-
- "#": "overwrite CTD attributes of some parameters (some are not possible, e.g. type)",
-
- "#": "for some tools the user needs to select the desired output type since detection by extension makes no sense for galaxy tools",
- "out_type": [{
- "CTD:required": true,
- "CTD:advanced": false
- }],
-
- "#": "SeedListGenerator with consensusXML input needs a dynamic number of outputs that depends on the content of the input, so we remove this options at the moment because its hard or impossible to implement in Galaxy, https://github.com/OpenMS/OpenMS/issues/4404 .. see also in parameter",
- "#": "FileInfo, MapStatistics, SequenceCoverageCalculator wo -out just writes to stdout. not wanted here",
- "#": "MzMLSplitter output prefix https://github.com/OpenMS/OpenMS/issues/4404",
- "#": "IDRipper: blacklist out (is doing the same as the output-prefix out-path)",
- "out": [{
- "CTD:is_list": false,
- "tools": ["SeedListGenerator"]
- }, {
- "CTD:required": true,
- "tools": ["FileInfo", "MapStatistics", "SequenceCoverageCalculator"]
- }, {
- "CTD:type": "output-prefix",
- "CTD:required": true,
- "CTD:restrictions": "mzml",
- "tools": ["MzMLSplitter"]
- }, {
- "value": "@",
- "tools": ["IDRipper"]
- }],
-
- "#": "Try to remove xml data type whereever possible",
- "#": "XTandem Adapter output is called .xml in OMS which is to unspecific -> use Galaxy's bioml",
- "xml_out": [{
- "CTD:restrictions": "bioml",
- "tools": ["XTandemAdapter"]
- }],
-
- "#": "IDFileConverter remove xml",
- "#": "OpenSwathWorkflow make in single file input and all outputs non-optional",
- "#": "XFDR does not need xml .. redundant with xquest.xml TODO check if list is up to date with each new release",
- "#": "SeedListGenerator: remove consensusXML https://github.com/OpenMS/OpenMS/issues/4404 .. see also out parameter",
- "in": [{
- "CTD:restrictions": "pepXML,protXML,mascotXML,omssaXML,bioml,psms,tsv,idXML,mzid,xquest.xml",
- "tools": ["IDFileConverter"]
- }, {
- "CTD:is_list": false,
- "tools": ["OpenSwathWorkflow"]
- }, {
- "CTD:restrictions": "idXML,mzid,xquest.xml",
- "tools": ["XFDR"]
- }, {
- "CTD:restrictions": "mzML,idXML,featureXML",
- "tools": ["SeedListGenerator"]
- }],
-
- "#": "IDMapper has in and spectra:in params, in is used in out as format_source",
- "#": "which does not work in Galaxy: https://github.com/galaxyproject/galaxy/pull/9493",
- "spectra:in": [{
- "CTD:name": "_in",
- "tools": ["IDMapper"]
- }],
-
- "#": "hardcoding prefix parameters which are not yet available in OMS but in CTDOpts https://github.com/OpenMS/OpenMS/pull/4527",
- "#": "output-prefix",
- "out_path": [{
- "CTD:type": "output-prefix",
- "CTD:required": true,
- "CTD:restrictions": "idXML",
- "tools": ["IDRipper"]
- }],
- "outputDirectory": [{
- "CTD:type": "output-prefix",
- "CTD:advanced": false,
- "CTD:required": true,
- "CTD:restrictions": "mzml",
- "tools": ["OpenSwathFileSplitter"]
- }],
-
- "#": "OpenSwathDIAPreScoring: https://github.com/OpenMS/OpenMS/pull/4443",
- "#": "SpectraSTSearchAdapter does not need xml .. redundant with pep.xml TODO check if list is up to date with each new release",
- "output_files": [{
- "CTD:required": true,
- "tools": ["OpenSwathDIAPreScoring"]
- }, {
- "CTD:restrictions": "txt,tsv,pep.xml,pepXML,html",
- "tools": ["SpectraSTSearchAdapter"]
-
- }]
-}
diff -r 0fc9ae55bcfc -r 016964c597f5 macros.xml
--- a/macros.xml Fri Nov 06 20:36:48 2020 +0000
+++ b/macros.xml Thu Dec 01 18:56:56 2022 +0000
@@ -3,14 +3,15 @@
You can edit this file to add your own macros, if you so desire, or you can
add additional macro files using the m/macros parameter -->
- 2.6
- 0
+ 2.8
+ 0
openms
openms-thirdparty
-
- blast
+
+ omssa
+ blast
@@ -21,6 +22,7 @@
+
@@ -32,23 +34,15 @@
-
-
-
-
-
-
-
-
-
-
+
-
- ^[^$]
-
- ^ *((?:\"[^\"]*\" +)|(?:[^ \"]+ +))*((?:\"[^\"]*\")|(?:[^ \"]+)) *$
+
+ ^[^$]
+ ^ *((?:\"[^\"]*\" +)|(?:[^ \"]+ +))*((?:\"[^\"]*\")|(?:[^ \"]+)) *$
@@ -64,8 +58,8 @@
-
- ^ *[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?( *[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)* *$
+
+ ^ *[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?( *[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)* *$
@@ -78,8 +72,8 @@
-
- ^ *[+-]?[0-9]+( *[+-]?[0-9]+)* *$
+
+ ^ *[+-]?[0-9]+( *[+-]?[0-9]+)* *$
@@ -119,11 +113,11 @@
diff -r 0fc9ae55bcfc -r 016964c597f5 macros_autotest.xml
--- a/macros_autotest.xml Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27205 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r 0fc9ae55bcfc -r 016964c597f5 macros_discarded_auto.xml
--- a/macros_discarded_auto.xml Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,378 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r 0fc9ae55bcfc -r 016964c597f5 macros_test.xml
--- a/macros_test.xml Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,545 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -r 0fc9ae55bcfc -r 016964c597f5 prepare_test_data_manual.sh
--- a/prepare_test_data_manual.sh Fri Nov 06 20:36:48 2020 +0000
+++ b/prepare_test_data_manual.sh Thu Dec 01 18:56:56 2022 +0000
@@ -86,10 +86,13 @@
PhosphoScoring -in spectra.mzML -id MSGFPlusAdapter_1_out1.tmp -out PhosphoScoring.idxml > PhosphoScoring.stdout 2> stderr
if [[ "$?" -ne "0" ]]; then >&2 echo 'PhosphoScoring failed'; >&2 echo -e "stderr:\n$(cat stderr | sed 's/^/ /')"; fi
-PSMFeatureExtractor -test -in MSGFPlusAdapter_1_out.idXML XTandemAdapter_1_out.idXML -multiple_search_engines -skip_db_check -out PSMFeatureExtractor.idxml > PSMFeatureExtractor_1.stdout 2> stderr
+# TODO PSMFeatureExtractor should have auto tests with 2.7 https://github.com/OpenMS/OpenMS/pull/5087
+PSMFeatureExtractor -test -in MSGFPlusAdapter_1_out.idXML XTandemAdapter_1_out.idXML -multiple_search_engines -skip_db_check -out_type idXML -out PSMFeatureExtractor.idxml > PSMFeatureExtractor_1.stdout 2> stderr
if [[ "$?" -ne "0" ]]; then >&2 echo 'PSMFeatureExtractor_1 failed'; >&2 echo -e "stderr:\n$(cat stderr | sed 's/^/ /')"; fi
-PSMFeatureExtractor -test -in MSGFPlusAdapter_1_out.idXML XTandemAdapter_1_out.idXML -multiple_search_engines -skip_db_check -out PSMFeatureExtractor.mzid > PSMFeatureExtractor_2.stdout 2> stderr
+PSMFeatureExtractor -test -in MSGFPlusAdapter_1_out.idXML XTandemAdapter_1_out.idXML -multiple_search_engines -skip_db_check -out_type mzid -out PSMFeatureExtractor.mzid > PSMFeatureExtractor_2.stdout 2> stderr
if [[ "$?" -ne "0" ]]; then >&2 echo 'PSMFeatureExtractor_2 failed'; >&2 echo -e "stderr:\n$(cat stderr | sed 's/^/ /')"; fi
+PSMFeatureExtractor -test -in MSGFPlusAdapter_1_out.idXML -out_type idXML -out PSMFeatureExtractor_3.idXML > PSMFeatureExtractor_3.stdout 2> stderr
+if [[ "$?" -ne "0" ]]; then >&2 echo 'PSMFeatureExtractor_3 failed'; >&2 echo -e "stderr:\n$(cat stderr | sed 's/^/ /')"; fi
QCCalculator -test -in OpenPepXL_input.mzML -out QCCalculator1.qcML > QCCalculator_1.stdout 2> stderr
if [[ "$?" -ne "0" ]]; then >&2 echo 'QCCalculator_1 failed'; >&2 echo -e "stderr:\n$(cat stderr | sed 's/^/ /')"; fi
diff -r 0fc9ae55bcfc -r 016964c597f5 readme.md
--- a/readme.md Fri Nov 06 20:36:48 2020 +0000
+++ b/readme.md Thu Dec 01 18:56:56 2022 +0000
@@ -22,11 +22,14 @@
Manual updates should only be done to
-- the `@GALAXY_VERSION@"` token in `macros.xml`
- and the manually contributed tests in `macros_test.xml` (The goal is that all
tools that do not have an automatically generated test are covered here)
- the `hardcoded_params.json` files
+Wrapper versions are managed in `bump.json`. For tools listed in the file
+the wrapper version will be set accordingly and otherwise `0` is used.
+For a major update of the tool version the bump file should be reset (to `{}`).
+
In a few cases patches may be acceptable.
Installation
@@ -71,10 +74,15 @@
Preprocessing:
-- For each input / output data set parameter a directory is crated (named by
- the parameter)
- For input data set parameters the links to the actual location of the data
- sets are created
+ sets are created, the link names are `element_identifier`.`EXT`, where `EXT`
+ is an extension that is known by OpenMS
+- In order to avoid name collisions for the created links each is placed in a
+ unique directory: `PARAM_NAME/DATASET_ID`, where `PARAM_NAME` is the name
+ of the parameter and `DATASET_ID` is the id of the Galaxy dataset
+- the same happens for output parameters that are in 1:1 correspondence with
+ an input parameter
+
Main:
diff -r 0fc9ae55bcfc -r 016964c597f5 test-data.sh
--- a/test-data.sh Fri Nov 06 20:36:48 2020 +0000
+++ b/test-data.sh Thu Dec 01 18:56:56 2022 +0000
@@ -1,22 +1,25 @@
#!/usr/bin/env bash
-VERSION=2.6
-FILETYPES="filetypes.txt"
-CONDAPKG="https://anaconda.org/bioconda/openms/2.6.0/download/linux-64/openms-2.6.0-h4afb90d_0.tar.bz2"
+VERSION=2.8
+FILETYPES="aux/filetypes.txt"
+CONDAPKG="https://anaconda.org/bioconda/openms/2.8.0/download/linux-64/openms-2.8.0-h7ca0330_0.tar.bz2"
# import the magic
. ./generate-foo.sh
# install conda
if [ -z "$tmp" ]; then
- tmp=$(mktemp -d)
- created="yes"
+ tmp=$(mktemp -d)
+ created="yes"
fi
export OPENMSGIT="$tmp/OpenMS$VERSION.0-git"
export OPENMSPKG="$tmp/OpenMS$VERSION-pkg/"
-export OPENMSENV="$tmp/OpenMS$VERSION-env"
-export CTDCONVERTER="$tmp/CTDConverter"
+export OPENMSENV="OpenMS$VERSION-env"
+
+if [ -z "$CTDCONVERTER" ]; then
+ export CTDCONVERTER="$tmp/CTDConverter"
+fi
if [[ -z "$1" ]]; then
autotests="/dev/null"
@@ -25,11 +28,11 @@
fi
if type conda > /dev/null; then
- true
+ true
else
- wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
- bash Miniconda3-latest-Linux-x86_64.sh -b -p "$tmp/miniconda"
- source "$tmp/miniconda/bin/activate"
+ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
+ bash Miniconda3-latest-Linux-x86_64.sh -b -p "$tmp/miniconda"
+ source "$tmp/miniconda/bin/activate"
fi
eval "$(conda shell.bash hook)"
@@ -42,24 +45,27 @@
echo "Clone OpenMS $VERSION sources"
if [[ ! -d $OPENMSGIT ]]; then
- git clone -b release/$VERSION.0 https://github.com/OpenMS/OpenMS.git $OPENMSGIT
- cd $OPENMSGIT
- git submodule init
- git submodule update
- cd -
+ # TODO >2.8 reenable original release branch .. also in else branch
+ # the plus branch contains commits from https://github.com/OpenMS/OpenMS/pull/5920 and https://github.com/OpenMS/OpenMS/pull/5917
+ # git clone -b release/$VERSION.0 https://github.com/OpenMS/OpenMS.git $OPENMSGIT
+ git clone -b release/$VERSION.0-plus https://github.com/bernt-matthias/OpenMS.git $OPENMSGIT
+ cd $OPENMSGIT
+ git submodule init
+ git submodule update
+ cd -
else
- cd $OPENMSGIT
- git pull origin release/$VERSION.0
- cd -
+ cd $OPENMSGIT
+ git pull origin release/$VERSION.0-plus
+ cd -
fi
echo "Create OpenMS $VERSION conda env"
# TODO currently add lxml (needed by CTDConverter)
# TODO for some reason a to recent openjdk is used
if conda env list | grep "$OPENMSENV"; then
- true
+ true
else
- conda create -y --quiet --override-channels --channel iuc --channel conda-forge --channel bioconda --channel defaults -p $OPENMSENV openms=$VERSION openms-thirdparty=$VERSION ctdopts=1.4 lxml
+ conda create -y --quiet --override-channels --channel iuc --channel conda-forge --channel bioconda --channel defaults -n $OPENMSENV openms=$VERSION openms-thirdparty=$VERSION omssa=2.1.9 ctdopts=1.5 lxml
# chmod -R u-w $OPENMSENV
fi
###############################################################################
@@ -69,10 +75,10 @@
echo "Download OpenMS $VERSION package $CONDAPKG"
if [[ ! -d $OPENMSPKG ]]; then
- mkdir $OPENMSPKG
- wget -q -P $OPENMSPKG/ "$CONDAPKG"
- tar -xf $OPENMSPKG/"$(basename $CONDAPKG)" -C $OPENMSPKG/
- rm $OPENMSPKG/"$(basename $CONDAPKG)"
+ mkdir $OPENMSPKG
+ wget -q -P $OPENMSPKG/ "$CONDAPKG"
+ tar -xf $OPENMSPKG/"$(basename $CONDAPKG)" -C $OPENMSPKG/
+ rm $OPENMSPKG/"$(basename $CONDAPKG)"
fi
###############################################################################
@@ -81,40 +87,46 @@
###############################################################################
echo "Clone CTDConverter"
if [[ ! -d $CTDCONVERTER ]]; then
- #git clone https://github.com/WorkflowConversion/CTDConverter.git CTDConverter
- git clone -b topic/cdata https://github.com/bernt-matthias/CTDConverter.git $CTDCONVERTER
+ #git clone https://github.com/WorkflowConversion/CTDConverter.git CTDConverter
+ git clone -b topic/fix-selects2 https://github.com/bernt-matthias/CTDConverter.git $CTDCONVERTER
else
- cd $CTDCONVERTER
- git pull origin topic/cdata
- cd -
+ cd $CTDCONVERTER
+ git pull origin topic/fix-selects2
+ cd -
fi
+conda activate $OPENMSENV
+cd $CTDCONVERTER
+python -m pip install . --no-deps
+cd -
+conda deactivate
-###############################################################################
-## copy all the test data files to test-data
-## most of it (outputs) will be overwritten later, but its needed for
-## prepare_test_data
-###############################################################################
+
+# ###############################################################################
+# ## copy all the test data files to test-data
+# ## most of it (outputs) will be overwritten later, but its needed for
+# ## prepare_test_data
+# ###############################################################################
echo "Get test data"
-find test-data -type f,l,d ! -name "*fa" ! -name "*loc" -delete
+find test-data -type f,l,d ! -name "*fa" ! -name "*loc" ! -name "test-data" -delete
cp $(find $OPENMSGIT/src/tests/topp/ -type f | grep -Ev "third_party_tests.cmake|CMakeLists.txt|check_ini") test-data/
cp -r $OPENMSGIT/share/OpenMS/MAPPING/ test-data/
cp -r $OPENMSGIT/share/OpenMS/CHEMISTRY test-data/
cp -r $OPENMSGIT/share/OpenMS/examples/ test-data/
-if [[ ! -f test-data/MetaboliteSpectralDB.mzML ]]; then
- wget -nc https://abibuilder.informatik.uni-tuebingen.de/archive/openms/Tutorials/Data/latest/Example_Data/Metabolomics/databases/MetaboliteSpectralDB.mzML
- mv MetaboliteSpectralDB.mzML test-data/
+if [ ! -f test-data/MetaboliteSpectralDB.mzML ]; then
+ wget -nc https://abibuilder.cs.uni-tuebingen.de/archive/openms/Tutorials/Data/latest/Example_Data/Metabolomics/databases/MetaboliteSpectralDB.mzML
+ mv MetaboliteSpectralDB.mzML test-data/
fi
ln -fs TOFCalibration_ref_masses test-data/TOFCalibration_ref_masses.txt
ln -fs TOFCalibration_const test-data/TOFCalibration_const.csv
if [ ! -d test-data/pepnovo_models/ ]; then
- mkdir -p /tmp/pepnovo
- wget -nc http://proteomics.ucsd.edu/Software/PepNovo/PepNovo.20120423.zip
- unzip PepNovo.20120423.zip -d /tmp/pepnovo/
- mv /tmp/pepnovo/Models test-data/pepnovo_models/
- rm PepNovo.20120423.zip
- rm -rf /tmp/pepnovo
+ mkdir -p /tmp/pepnovo
+ wget -nc http://proteomics.ucsd.edu/Software/PepNovo/PepNovo.20120423.zip
+ unzip PepNovo.20120423.zip -d /tmp/pepnovo/
+ mv /tmp/pepnovo/Models test-data/pepnovo_models/
+ rm PepNovo.20120423.zip
+ rm -rf /tmp/pepnovo
fi
###############################################################################
## generate ctd files using the binaries in the conda package
@@ -124,17 +136,13 @@
rm -rf ctd
mkdir -p ctd
-# TODO because of https://github.com/OpenMS/OpenMS/issues/4641
-# this needs to be done from within test-data
-cd test-data
for i in $OPENMSPKG/bin/*
do
- b=$(basename $i)
- echo $b
- $b -write_ctd ../ctd/
- sed -i -e 's/²/^2/' ../ctd/$b.ctd
+ b=$(basename $i)
+ echo $b
+ $b -write_ctd ctd/
+ sed -i -e 's/²/^2/' ctd/$b.ctd
done
-cd -
###############################################################################
## fix ini files: OpenMS test data contains ini files with outdated ini files.
## e.g. variables might be in different nodes, outdated variables present, new
@@ -146,17 +154,17 @@
echo "Update test INI files"
for ini in test-data/*ini
do
- tool=$(cat $ini | grep 'NODE name="' | head -n 1 | sed 's/.*name="\([^"]\+\)".*/\1/')
- bin=$(which $tool)
- if [[ -z $bin ]]; then
+ tool=$(cat $ini | grep 'NODE name="' | head -n 1 | sed 's/.*name="\([^"]\+\)".*/\1/')
+ bin=$(which $tool)
+ if [[ -z $bin ]]; then
>&2 echo "missing binary to convert $ini"
- continue
- fi
- cp $ini $ini.backup
- $bin -ini $ini -write_ini $ini > $ini.stdout 2> $ini.stderr
- if [[ "$?" -ne "0" ]]; then
- >&2 echo "could not convert $ini"
- fi
+ continue
+ fi
+ cp $ini $ini.backup
+ $bin -ini $ini -write_ini $ini > $ini.stdout 2> $ini.stderr
+ if [[ "$?" -ne "0" ]]; then
+ >&2 echo "could not convert $ini"
+ fi
done
###############################################################################
@@ -185,17 +193,17 @@
prepare_test_data >> prepare_test_data.sh #tmp_test_data.sh
-# prepare_test_data > tmp_test_data.sh
-# # remove calls not needed for the tools listed in any .list file
-# echo LIST $LIST
-# if [ ! -z "$LIST" ]; then
-# REX=$(echo $LIST | sed 's/ /\n/g' | sed 's@.*/\([^/]\+\).xml$@\1@' | tr '\n' '|' | sed 's/|$//')
-# else
-# REX=".*"
-# fi
-# echo REX $REX
-# cat tmp_test_data.sh | egrep "($REX)" >> prepare_test_data.sh
-# rm tmp_test_data.sh
+## prepare_test_data > tmp_test_data.sh
+## # remove calls not needed for the tools listed in any .list file
+## echo LIST $LIST
+## if [ ! -z "$LIST" ]; then
+## REX=$(echo $LIST | sed 's/ /\n/g' | sed 's@.*/\([^/]\+\).xml$@\1@' | tr '\n' '|' | sed 's/|$//')
+## else
+## REX=".*"
+## fi
+## echo REX $REX
+## cat tmp_test_data.sh | egrep "($REX)" >> prepare_test_data.sh
+## rm tmp_test_data.sh
echo "Execute test shell script"
chmod u+x prepare_test_data.sh
@@ -204,14 +212,13 @@
cd - || exit
-###############################################################################
-## create/update test data for the manually generated tests
-## - run convert once with the manual tests only and
-## - update test-data (needs to run 2x)
-###############################################################################
+# ###############################################################################
+# ## create/update test data for the manually generated tests
+# ## - run convert once with the manual tests only and
+# ## - update test-data (needs to run 2x)
+# ###############################################################################
echo "Execute test shell script for manually curated tests"
chmod u+x prepare_test_data_manual.sh
-
cd ./test-data || exit
../prepare_test_data_manual.sh
cd - || exit
@@ -220,22 +227,28 @@
###############################################################################
## auto generate tests
###############################################################################
+
echo "Write test macros to $autotests"
echo "" > "$autotests"
-for i in $(ls *xml |grep -v macros)
+
+for i in $(ls ctd/*ctd)
do
- b=$(basename "$i" .xml)
- get_tests2 "$b" >> "$autotests"
+ b=$(basename "$i" .ctd)
+ get_tests2 "$b" >> "$autotests"
done
echo "" >> "$autotests"
-echo "Create test data links"
-link_tmp_files
+# echo "Create test data links"
+# Breaks DecoyDatabase
+# link_tmp_files
# tests for tools using output_prefix parameters can not be auto generated
# hence we output the tests for manual curation in macros_test.xml
# and remove them from the autotests
-# -> OpenSwathFileSplitter IDRipper MzMLSplitter
+# -> OpenSwathFileSplitter IDRipper MzMLSplitter SeedListGenerator
+# TODO reevaluate in >2.8
+# - https://github.com/OpenMS/OpenMS/pull/5873
+# - https://github.com/OpenMS/OpenMS/pull/5912
#
# Furthermore we remove tests for tools without binaries in conda
# -> MSFragger MaRaClusterAdapter NovorAdapter
@@ -243,23 +256,23 @@
# not able to specify composite test data
# -> SpectraSTSearchAdapter
if [[ ! -z "$1" ]]; then
- echo "" > macros_discarded_auto.xml
- for i in OpenSwathFileSplitter IDRipper MzMLSplitter MSFraggerAdapter MaRaClusterAdapter NovorAdapter SpectraSTSearchAdapter
- do
- echo "" >> macros_discarded_auto.xml
- xmlstarlet sel -t -c "/macros/xml[@name='autotest_$i']/test" macros_autotest.xml >> macros_discarded_auto.xml
- echo "" >> macros_discarded_auto.xml
- xmlstarlet ed -d "/macros/xml[@name='autotest_$i']/test" macros_autotest.xml > tmp
- mv tmp macros_autotest.xml
- done
- >&2 echo "discarded autogenerated macros for curation in macros_discarded_auto.xml"
+ echo "" > macros_discarded_auto.xml
+ for i in OpenSwathFileSplitter IDRipper MzMLSplitter SeedListGenerator MSFraggerAdapter MaRaClusterAdapter NovorAdapter SpectraSTSearchAdapter
+ do
+ echo "" >> macros_discarded_auto.xml
+ xmlstarlet sel -t -c "/macros/xml[@name='autotest_$i']/test" macros_autotest.xml >> macros_discarded_auto.xml
+ echo "" >> macros_discarded_auto.xml
+ xmlstarlet ed -d "/macros/xml[@name='autotest_$i']/test" macros_autotest.xml > tmp
+ mv tmp macros_autotest.xml
+ done
+ >&2 echo "discarded autogenerated macros for curation in macros_discarded_auto.xml"
fi
conda deactivate
## remove broken symlinks in test-data
find test-data/ -xtype l -delete
-# if [ ! -z "$created" ]; then
-# echo "Removing temporary directory"
-# rm -rf "$tmp"
-# fi
+if [ ! -z "$created" ]; then
+ echo "Removing temporary directory"
+ rm -rf "$tmp"
+fi
diff -r 0fc9ae55bcfc -r 016964c597f5 test-data/pepnovo_models.loc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/pepnovo_models.loc Thu Dec 01 18:56:56 2022 +0000
@@ -0,0 +1,13 @@
+#name value path
+default_models CID_IT_TRYP ${__HERE__}/pepnovo_models/
+default_models LTQ_COMP ${__HERE__}/pepnovo_models/
+default_models DBC4_PEAK ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_TAG5 ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_TAG6 ${__HERE__}/pepnovo_models/
+default_models ITDNV_PEAK ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_SCORE ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_TAG3 ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_DNVPART ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_TAG4 ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_DB ${__HERE__}/pepnovo_models/
+default_models CID_IT_TRYP_CSP ${__HERE__}/pepnovo_models/
diff -r 0fc9ae55bcfc -r 016964c597f5 test-data/random.fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/random.fa Thu Dec 01 18:56:56 2022 +0000
@@ -0,0 +1,18 @@
+>RND24402 Randomly generated sequence, created by ExPASy tool RandSeq, using average amino acid composition
+LALLTDKYSVTKSIKGYAGQQQKCTDDEGLAEDSAAMSLVPIRAAWTISVSVDLFYLGIV
+TNVTKDSVEHLVGIPLVTHEFMASRCEMRGQVVSATFGSWQKAESKAYRIPLKATPLDEF
+VESAVYLFGGSSNEYECVLIGNSHPVLIFLDIDAVPGARKPRTGFFMAEGFHSKGETRAL
+VGKSPPLGEYRKGAFHFTFPIKEAIRLGPPKKRIMGYRDALEGGLNHYVQTQVLVLLPMI
+QVARRWENGLGLLVGKFLKLPTHPLDLNQVTLCWSEAVTEDNKRFLLTIKTSAQGKSAPT
+SHINYVPQHNSMELMAINGSPFAAQHKSNDEIESMRDLSKLYADAETLESHGERGVRHQA
+TETKISKVTNLRRKLPQLLDLNVVDNACNWESVGAHVLEYVLVNLYLKELQEPKVELQPR
+LNETTMKAGASSLGVESGASAHSFYKGGVSEAKLRFRHVATPAAARIWWCVVMFRINRRY
+DGITYNSVGEQLSGVHEYVRAAQLFGLTTGKNLRSTGIVIIKLSTAIDLECLVQAKPKEA
+YVLANDYIGAKPHPARLETGPALVLFIVETINNDTLNAAILITALGGKFLNVRPDLLFGV
+QALFGCVRMFRHADCTIGREKFVQTEISHKAKFLYEINEFFLERILQFEEAKSPVGAPAY
+DIPIGRGLVMDSSTDLWNIYVVELISGQEKRTGIDPDTPMGTSHNLYMTDARLDERDQRS
+FLNSEFVKPSKLANGSEWADPYVEPDKTEVIAFFPATLIVIMADGSALNGQVCIQPAKDN
+SKMADDLATVHIGQDRPCDWGISASHEYDEVNRPARINGVMMQQLMAEDNQGPGASPRDQ
+MGDADDLKEIKWNKYVIDNEIIGRERGISAERVKIFLGDTLTARGLLDSPPGQTKVFDLR
+PRQSDKNQSGMFKRDQNAMYFPLEYDRIGAQTDTGSLYSTLITKFASISIDLVKLSMPRE
+KQIDEERLHSEFIENQKRSALPAVQKNLACISCVEACRGT
diff -r 0fc9ae55bcfc -r 016964c597f5 test-data/random_RNA.fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/random_RNA.fa Thu Dec 01 18:56:56 2022 +0000
@@ -0,0 +1,2 @@
+> random RNA
+GUGUUACUGCCACGAAACAAAAUGUUCAAGACACCGGGCGCCAUCUGUAUAUUACUCGCCAAUCAGACGGUCUGCAACGCUACAGACAUGGAGCUCAGCGCUGACGAUGUCGCCGGACCAAGUACGAUCACUUUGCUCGUGCAAAUGUUCGUCCGCAUUGGGCACUAUAACUCGAAUUGUCGAAUCCGGGUGGCGAGCCGCCACUUAUAGGAUAAAUAUUCAAACUAACAUUAUGGCGCCAAAUCUGCAAUCUCUACUUUAGACAUUAUAUACCCACAUUUACAAUUAGAGUUAUUAUUAGUUAACGUGUGCCAGAGCAGGGAUGGCUCUUGUCAGCCAUAGUUGUGUGAACGGGCUGUAUUUCCUUCCUAAUUAUAGAGCGGCACCGGAAAGCAAUGCACGAUCCACGAGGGCACUUCACAUGGUCACAAACAGUCAUUCUGGUACCCUGAUUCGUUCCCGAAAGGGAAGUAUAUACACGGCCCCCGUGUAUAUCGCCAGUCACACGGCAGGAGCGAGAGUUCGUUUGUAUACAUGCCCAGGAGCCUUCUCUAACUUUUGAAGCUGUGCAACUUUGUUGGCGCGUCACCACUAAGUCAGCUUAAUAGACAGCAGAUGGGAGAAUUUACCAUUUCAUUUUGUCCGAGCUGAUACCGGUAGGUCAUCUCUAAUCACCCGUUAUCCUCUCGUAAUAUAAUCGCUACUAAGGUAUGAAGGUGUCUGCGAAAGGUAACGUAAAUCAUUCUCGGCUCCUUGCAAAGUACGACUAGGAUCCAUCGUACACAUCCGGACGAAGAUGUAAAAUUGACGCCCCUGUAGGCCGUGAGACAGACGUGAGCCAAACCAUCUGCUCUACUUCUGGAGGCCUUGAAUAGUGGCGCGUUGUGUAAUCUUAAGAGAGAUUUUACUUGGAAUUACAGCCUACUUUGACCAGUAGCGCAUUGUGAACAAAUAUUCCCGUACGCGUCCAAUUGCAGCAAAACGUGGGCCUGUGUCCAGU
diff -r 0fc9ae55bcfc -r 016964c597f5 tools_blacklist.txt
--- a/tools_blacklist.txt Fri Nov 06 20:36:48 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-# seems not possible for 2.5 https://github.com/OpenMS/OpenMS/issues/4426
-# DigestorMotif
-
-# deprecated https://abibuilder.informatik.uni-tuebingen.de/archive/openms/Documentation/release/latest/html/UTILS_IDDecoyProbability.html
-# https://abibuilder.informatik.uni-tuebingen.de/archive/openms/Documentation/release/latest/html/a16242.html
-IDDecoyProbability
-
-# personal communication with author V. Bafna:
-# "InsPect is no longer maintained as there are many better tools including MS-GF+"
-InspectAdapter
-
-# licence? see https://github.com/bioconda/bioconda-recipes/issues/18953
-#MSFraggerAdapter
-
-# https://github.com/OpenMS/OpenMS/issues/4550#issuecomment-594065727
-ProteomicsLFQ
-
-# https://github.com/OpenMS/OpenMS/issues/4401
-InclusionExclusionListCreator
-RTPredict
-PTPredict