From 9790cad21b6c9824cc2fcb39ff3b77ef2dc111fa Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 14:20:46 +0100 Subject: [PATCH 01/14] Add setup.py, correct line teminaison, add shebang --- setup.py | 14 ++ suppa.py | 205 +++++++++--------- {lib => suppa}/__init__.py | 0 .../__pycache__/__init__.cpython-35.pyc | Bin .../__pycache__/cluster_tools.cpython-35.pyc | Bin .../__pycache__/diff_tools.cpython-35.pyc | Bin .../__pycache__/event.cpython-35.pyc | Bin .../__pycache__/gtf_store.cpython-35.pyc | Bin .../__pycache__/optics.cpython-35.pyc | Bin .../__pycache__/tools.cpython-35.pyc | Bin .../__pycache__/var_event.cpython-35.pyc | Bin {lib => suppa}/cluster_tools.py | 2 +- {lib => suppa}/diff_tools.py | 0 {lib => suppa}/event.py | 2 +- eventClusterer.py => suppa/eventClusterer.py | 2 +- eventGenerator.py => suppa/eventGenerator.py | 6 +- fileMerger.py => suppa/fileMerger.py | 0 {lib => suppa}/gtf_store.py | 0 .../multipleFieldSelection.py | 0 {lib => suppa}/optics.py | 0 psiCalculator.py => suppa/psiCalculator.py | 4 +- psiPerGene.py => suppa/psiPerGene.py | 4 +- .../significanceCalculator.py | 2 +- {lib => suppa}/tools.py | 2 +- {lib => suppa}/var_event.py | 2 +- 25 files changed, 130 insertions(+), 115 deletions(-) create mode 100644 setup.py mode change 100644 => 100755 suppa.py rename {lib => suppa}/__init__.py (100%) rename {lib => suppa}/__pycache__/__init__.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/cluster_tools.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/diff_tools.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/event.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/gtf_store.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/optics.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/tools.cpython-35.pyc (100%) rename {lib => suppa}/__pycache__/var_event.cpython-35.pyc (100%) rename {lib => suppa}/cluster_tools.py (99%) rename {lib => suppa}/diff_tools.py (100%) rename {lib => suppa}/event.py (99%) rename eventClusterer.py => suppa/eventClusterer.py (99%) rename eventGenerator.py => suppa/eventGenerator.py (98%) rename fileMerger.py => suppa/fileMerger.py (100%) rename {lib => suppa}/gtf_store.py (100%) rename multipleFieldSelection.py => suppa/multipleFieldSelection.py (100%) rename {lib => suppa}/optics.py (100%) rename psiCalculator.py => suppa/psiCalculator.py (99%) rename psiPerGene.py => suppa/psiPerGene.py (98%) rename significanceCalculator.py => suppa/significanceCalculator.py (99%) rename {lib => suppa}/tools.py (99%) rename {lib => suppa}/var_event.py (99%) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..dd7988c --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup(name='SUPPA', + version='2.3', + description='SUPPA2: Fast quantification of differential splicing', + url='https://github.com/comprna/SUPPA', + scripts=['suppa.py'], + author="comprna", + packages=['suppa'], + install_requires=['scipy', 'numpy', 'pandas', 'statsmodels', 'sklearn'], + python_requires='>=3', +) diff --git a/suppa.py b/suppa.py old mode 100644 new mode 100755 index 8fa0bc8..4cc1783 --- a/suppa.py +++ b/suppa.py @@ -1,102 +1,103 @@ -# -*- coding: utf-8 -*- -""" -Created on Wed Aug 06 17:51:05 2014 - -@author: Gael P Alamancos -@email: gael.perez[at]upf.edu -""" - -import fileMerger as joinFiles -import psiPerGene as psiPerIsoform -import psiCalculator as psiPerEvent -import eventGenerator as generateEvents -import eventClusterer as clusterAnalysis -import significanceCalculator as diffSplice -import logging -import argparse -import sys - - -description = "Description:\n\n" + \ - "SUPPA allows you to generate all the possible Alternative Splicing events from an annotation file, \n" \ - "calculate the PSI values per event, calculate differential splicing across multiple conditions \n" \ - "with replicates, and cluster events across conditions \n" \ - "For further information, see the help of each subcommand." - -parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter, prog='SUPPA') -# Version -parser.add_argument('-v','--version', action='version', version='%(prog)s 2.3') -subparsers = parser.add_subparsers() - -# EventGenerator parser -eventGeneratorSubparser = subparsers.add_parser( - "generateEvents", parents=[generateEvents.parser], - help="Calculates the Alternative Splicing events from an annotation file.") -eventGeneratorSubparser.set_defaults(which="generateEvents") - -# psiCalculator parser -psiCalculatorSubparser = subparsers.add_parser( - "psiPerEvent", parents=[psiPerEvent.parser], - help="Calculates the PSI value for each event previously generated.") -psiCalculatorSubparser.set_defaults(which="psiPerEvent") - -# psiPerGene parser -psiPerGeneSubparser = subparsers.add_parser( - "psiPerIsoform", parents=[psiPerIsoform.parser], - help="Calculates the PSI value for each isoform.") -psiPerGeneSubparser.set_defaults(which="psiPerIsoform") - -# significanceCalculator parser -significanceCalculatorSubparser = subparsers.add_parser( - "diffSplice", parents=[diffSplice.parser], - help="Calculates differentially spliced events across multiple conditions.") -significanceCalculatorSubparser.set_defaults(which="diffSplice") - -# eventClusterer parser -eventClustererSubparser = subparsers.add_parser( - "clusterEvents", parents=[clusterAnalysis.parser], - help="Calculates clusters of events across conditions.") -eventClustererSubparser.set_defaults(which="clusterEvents") - -# fileMerger parser -fileMergerSubparser = subparsers.add_parser( - "joinFiles", parents=[joinFiles.parser], - help="Join multiple tab separated files into a single file.") -fileMergerSubparser.set_defaults(which="joinFiles") - -# Setting logging preferences -logger = logging.getLogger(__name__) - - -def main(): - - if len(sys.argv) == 1: - parser.print_help() - sys.exit(1) - - try: - args = parser.parse_args() - if args.which == "generateEvents": - generateEvents.parser = parser # Setting the module aparser - generateEvents.main() - elif args.which == "psiPerEvent": - psiPerEvent.parser = parser # Setting the module parser - psiPerEvent.main() - elif args.which == "psiPerIsoform": - psiPerIsoform.parser = parser # Setting the module parser - psiPerIsoform.main() - elif args.which == "diffSplice": - diffSplice.parser = parser # Setting the module parser - diffSplice.main() - elif args.which == "clusterEvents": - clusterAnalysis.parser = parser # Setting the module parser - clusterAnalysis.main() - elif args.which == "joinFiles": - joinFiles.parser = parser # Setting the module parser - joinFiles.main() - except Exception: - logger.error("Unknown error: {}".format(sys.exc_info())) - sys.exit(1) - -if __name__ == '__main__': - main() +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Wed Aug 06 17:51:05 2014 + +@author: Gael P Alamancos +@email: gael.perez[at]upf.edu +""" + +import suppa.fileMerger as joinFiles +import suppa.psiPerGene as psiPerIsoform +import suppa.psiCalculator as psiPerEvent +import suppa.eventGenerator as generateEvents +import suppa.eventClusterer as clusterAnalysis +import suppa.significanceCalculator as diffSplice +import logging +import argparse +import sys + + +description = "Description:\n\n" + \ + "SUPPA allows you to generate all the possible Alternative Splicing events from an annotation file, \n" \ + "calculate the PSI values per event, calculate differential splicing across multiple conditions \n" \ + "with replicates, and cluster events across conditions \n" \ + "For further information, see the help of each subcommand." + +parser = argparse.ArgumentParser(description=description, formatter_class=argparse.RawTextHelpFormatter, prog='SUPPA') +# Version +parser.add_argument('-v','--version', action='version', version='%(prog)s 2.3') +subparsers = parser.add_subparsers() + +# EventGenerator parser +eventGeneratorSubparser = subparsers.add_parser( + "generateEvents", parents=[generateEvents.parser], + help="Calculates the Alternative Splicing events from an annotation file.") +eventGeneratorSubparser.set_defaults(which="generateEvents") + +# psiCalculator parser +psiCalculatorSubparser = subparsers.add_parser( + "psiPerEvent", parents=[psiPerEvent.parser], + help="Calculates the PSI value for each event previously generated.") +psiCalculatorSubparser.set_defaults(which="psiPerEvent") + +# psiPerGene parser +psiPerGeneSubparser = subparsers.add_parser( + "psiPerIsoform", parents=[psiPerIsoform.parser], + help="Calculates the PSI value for each isoform.") +psiPerGeneSubparser.set_defaults(which="psiPerIsoform") + +# significanceCalculator parser +significanceCalculatorSubparser = subparsers.add_parser( + "diffSplice", parents=[diffSplice.parser], + help="Calculates differentially spliced events across multiple conditions.") +significanceCalculatorSubparser.set_defaults(which="diffSplice") + +# eventClusterer parser +eventClustererSubparser = subparsers.add_parser( + "clusterEvents", parents=[clusterAnalysis.parser], + help="Calculates clusters of events across conditions.") +eventClustererSubparser.set_defaults(which="clusterEvents") + +# fileMerger parser +fileMergerSubparser = subparsers.add_parser( + "joinFiles", parents=[joinFiles.parser], + help="Join multiple tab separated files into a single file.") +fileMergerSubparser.set_defaults(which="joinFiles") + +# Setting logging preferences +logger = logging.getLogger(__name__) + + +def main(): + + if len(sys.argv) == 1: + parser.print_help() + sys.exit(1) + + try: + args = parser.parse_args() + if args.which == "generateEvents": + generateEvents.parser = parser # Setting the module aparser + generateEvents.main() + elif args.which == "psiPerEvent": + psiPerEvent.parser = parser # Setting the module parser + psiPerEvent.main() + elif args.which == "psiPerIsoform": + psiPerIsoform.parser = parser # Setting the module parser + psiPerIsoform.main() + elif args.which == "diffSplice": + diffSplice.parser = parser # Setting the module parser + diffSplice.main() + elif args.which == "clusterEvents": + clusterAnalysis.parser = parser # Setting the module parser + clusterAnalysis.main() + elif args.which == "joinFiles": + joinFiles.parser = parser # Setting the module parser + joinFiles.main() + except Exception: + logger.error("Unknown error: {}".format(sys.exc_info())) + sys.exit(1) + +if __name__ == '__main__': + main() diff --git a/lib/__init__.py b/suppa/__init__.py similarity index 100% rename from lib/__init__.py rename to suppa/__init__.py diff --git a/lib/__pycache__/__init__.cpython-35.pyc b/suppa/__pycache__/__init__.cpython-35.pyc similarity index 100% rename from lib/__pycache__/__init__.cpython-35.pyc rename to suppa/__pycache__/__init__.cpython-35.pyc diff --git a/lib/__pycache__/cluster_tools.cpython-35.pyc b/suppa/__pycache__/cluster_tools.cpython-35.pyc similarity index 100% rename from lib/__pycache__/cluster_tools.cpython-35.pyc rename to suppa/__pycache__/cluster_tools.cpython-35.pyc diff --git a/lib/__pycache__/diff_tools.cpython-35.pyc b/suppa/__pycache__/diff_tools.cpython-35.pyc similarity index 100% rename from lib/__pycache__/diff_tools.cpython-35.pyc rename to suppa/__pycache__/diff_tools.cpython-35.pyc diff --git a/lib/__pycache__/event.cpython-35.pyc b/suppa/__pycache__/event.cpython-35.pyc similarity index 100% rename from lib/__pycache__/event.cpython-35.pyc rename to suppa/__pycache__/event.cpython-35.pyc diff --git a/lib/__pycache__/gtf_store.cpython-35.pyc b/suppa/__pycache__/gtf_store.cpython-35.pyc similarity index 100% rename from lib/__pycache__/gtf_store.cpython-35.pyc rename to suppa/__pycache__/gtf_store.cpython-35.pyc diff --git a/lib/__pycache__/optics.cpython-35.pyc b/suppa/__pycache__/optics.cpython-35.pyc similarity index 100% rename from lib/__pycache__/optics.cpython-35.pyc rename to suppa/__pycache__/optics.cpython-35.pyc diff --git a/lib/__pycache__/tools.cpython-35.pyc b/suppa/__pycache__/tools.cpython-35.pyc similarity index 100% rename from lib/__pycache__/tools.cpython-35.pyc rename to suppa/__pycache__/tools.cpython-35.pyc diff --git a/lib/__pycache__/var_event.cpython-35.pyc b/suppa/__pycache__/var_event.cpython-35.pyc similarity index 100% rename from lib/__pycache__/var_event.cpython-35.pyc rename to suppa/__pycache__/var_event.cpython-35.pyc diff --git a/lib/cluster_tools.py b/suppa/cluster_tools.py similarity index 99% rename from lib/cluster_tools.py rename to suppa/cluster_tools.py index f4d5cf8..5df9960 100644 --- a/lib/cluster_tools.py +++ b/suppa/cluster_tools.py @@ -13,7 +13,7 @@ from sklearn.cluster import DBSCAN from collections import defaultdict from sklearn.metrics import silhouette_score -from lib.optics import * +from .optics import * diff --git a/lib/diff_tools.py b/suppa/diff_tools.py similarity index 100% rename from lib/diff_tools.py rename to suppa/diff_tools.py diff --git a/lib/event.py b/suppa/event.py similarity index 99% rename from lib/event.py rename to suppa/event.py index c70c683..ae23847 100644 --- a/lib/event.py +++ b/suppa/event.py @@ -607,7 +607,7 @@ def process_events(my_gene, event, ioe_writer, gtf_writer, edge_len, th): gtf_writer.write(gtf_line, etype) # to avoid circular dependencies -from lib.var_event import * +from .var_event import * def create_event_classes(all_events, b_type): diff --git a/eventClusterer.py b/suppa/eventClusterer.py similarity index 99% rename from eventClusterer.py rename to suppa/eventClusterer.py index 881ad66..8094cb5 100644 --- a/eventClusterer.py +++ b/suppa/eventClusterer.py @@ -9,7 +9,7 @@ import os import logging -from lib.cluster_tools import cluster_analysis +from .cluster_tools import cluster_analysis from argparse import ArgumentParser, RawTextHelpFormatter diff --git a/eventGenerator.py b/suppa/eventGenerator.py similarity index 98% rename from eventGenerator.py rename to suppa/eventGenerator.py index 9d42b16..19853e8 100644 --- a/eventGenerator.py +++ b/suppa/eventGenerator.py @@ -9,9 +9,9 @@ import sys import logging from argparse import ArgumentParser, RawTextHelpFormatter -from lib.tools import * -from lib.gtf_store import * -from lib.event import * +from .tools import * +from .gtf_store import * +from .event import * # Setting argument parser # parser = argparse.ArgumentParser() diff --git a/fileMerger.py b/suppa/fileMerger.py similarity index 100% rename from fileMerger.py rename to suppa/fileMerger.py diff --git a/lib/gtf_store.py b/suppa/gtf_store.py similarity index 100% rename from lib/gtf_store.py rename to suppa/gtf_store.py diff --git a/multipleFieldSelection.py b/suppa/multipleFieldSelection.py similarity index 100% rename from multipleFieldSelection.py rename to suppa/multipleFieldSelection.py diff --git a/lib/optics.py b/suppa/optics.py similarity index 100% rename from lib/optics.py rename to suppa/optics.py diff --git a/psiCalculator.py b/suppa/psiCalculator.py similarity index 99% rename from psiCalculator.py rename to suppa/psiCalculator.py index 996ec9f..5cd9f9e 100644 --- a/psiCalculator.py +++ b/suppa/psiCalculator.py @@ -10,7 +10,7 @@ import logging import numpy as np from argparse import ArgumentParser, RawTextHelpFormatter -from lib.tools import * +from .tools import * description = \ @@ -183,4 +183,4 @@ def main(): logger.info("Done") if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/psiPerGene.py b/suppa/psiPerGene.py similarity index 98% rename from psiPerGene.py rename to suppa/psiPerGene.py index 0019f17..4d2e84c 100644 --- a/psiPerGene.py +++ b/suppa/psiPerGene.py @@ -10,8 +10,8 @@ import sys import logging from argparse import ArgumentParser, RawTextHelpFormatter -from lib.tools import * -from lib.gtf_store import * +from .tools import * +from .gtf_store import * description = \ diff --git a/significanceCalculator.py b/suppa/significanceCalculator.py similarity index 99% rename from significanceCalculator.py rename to suppa/significanceCalculator.py index 0ccb105..9e8e88a 100644 --- a/significanceCalculator.py +++ b/suppa/significanceCalculator.py @@ -12,7 +12,7 @@ import os import logging -from lib.diff_tools import multiple_conditions_analysis +from .diff_tools import multiple_conditions_analysis from argparse import * diff --git a/lib/tools.py b/suppa/tools.py similarity index 99% rename from lib/tools.py rename to suppa/tools.py index 276e5e6..20b705f 100644 --- a/lib/tools.py +++ b/suppa/tools.py @@ -9,7 +9,7 @@ import sys import logging from abc import ABCMeta, abstractmethod -from lib.event import * +from .event import * #Setting logging preferences diff --git a/lib/var_event.py b/suppa/var_event.py similarity index 99% rename from lib/var_event.py rename to suppa/var_event.py index 4da829e..b082068 100644 --- a/lib/var_event.py +++ b/suppa/var_event.py @@ -1,5 +1,5 @@ import itertools -from lib.event import Event +from .event import Event class VariableEvent(Event): From c05213709349e38bd4e859e8665f66b3bcc08cfd Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 14:23:22 +0100 Subject: [PATCH 02/14] Remove __pycache__ --- __pycache__/eventClusterer.cpython-35.pyc | Bin 3474 -> 0 bytes __pycache__/eventGenerator.cpython-35.pyc | Bin 3091 -> 0 bytes __pycache__/fileMerger.cpython-35.pyc | Bin 2672 -> 0 bytes __pycache__/psiCalculator.cpython-35.pyc | Bin 4719 -> 0 bytes __pycache__/psiPerGene.cpython-35.pyc | Bin 4463 -> 0 bytes .../significanceCalculator.cpython-35.pyc | Bin 4147 -> 0 bytes suppa/__pycache__/__init__.cpython-35.pyc | Bin 203 -> 0 bytes suppa/__pycache__/cluster_tools.cpython-35.pyc | Bin 8724 -> 0 bytes suppa/__pycache__/diff_tools.cpython-35.pyc | Bin 20870 -> 0 bytes suppa/__pycache__/event.cpython-35.pyc | Bin 21282 -> 0 bytes suppa/__pycache__/gtf_store.cpython-35.pyc | Bin 8384 -> 0 bytes suppa/__pycache__/optics.cpython-35.pyc | Bin 6338 -> 0 bytes suppa/__pycache__/tools.cpython-35.pyc | Bin 18099 -> 0 bytes suppa/__pycache__/var_event.cpython-35.pyc | Bin 23013 -> 0 bytes 14 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __pycache__/eventClusterer.cpython-35.pyc delete mode 100644 __pycache__/eventGenerator.cpython-35.pyc delete mode 100644 __pycache__/fileMerger.cpython-35.pyc delete mode 100644 __pycache__/psiCalculator.cpython-35.pyc delete mode 100644 __pycache__/psiPerGene.cpython-35.pyc delete mode 100644 __pycache__/significanceCalculator.cpython-35.pyc delete mode 100644 suppa/__pycache__/__init__.cpython-35.pyc delete mode 100644 suppa/__pycache__/cluster_tools.cpython-35.pyc delete mode 100644 suppa/__pycache__/diff_tools.cpython-35.pyc delete mode 100644 suppa/__pycache__/event.cpython-35.pyc delete mode 100644 suppa/__pycache__/gtf_store.cpython-35.pyc delete mode 100644 suppa/__pycache__/optics.cpython-35.pyc delete mode 100644 suppa/__pycache__/tools.cpython-35.pyc delete mode 100644 suppa/__pycache__/var_event.cpython-35.pyc diff --git a/__pycache__/eventClusterer.cpython-35.pyc b/__pycache__/eventClusterer.cpython-35.pyc deleted file mode 100644 index cf1db5d0cb339fa14c8f2b8419f7d2f5f76857b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3474 zcmZ`*OLrT$6}~fkYD9^$<5+Q%rf8csqNAZG#dcjbj;%;aqtuoaOFcPdPs#%gKysXU z8NlcOU~ur|NEzZ zy$0|R`d9PlUjuvBpx1r`-I+(<1oqw!aL60(Y<+&kF0iiAx-o}tnHBd8dUIau7O?jX z`WCR;!0rJ14Y0c~t{4FvqWa&?tM3E*oq>J;>>iBKmq^7ugZmJ1m6D44z#bUI+vPGo z0=5GT=|dl(Yj%yy9?H~9nU8_}-pG7X%Aoaqqm_LM><{o2MisjEA+SfL-v*9;K7cQ6 z5P!9K8)E^(#)hNLrM&gKkj;}}bf^6L;y<7dQUcc8PJ9|gRWUIG%$8jFe zR83+b`{dJEW5k__cs4b)fZf< zl=(DL-830>IZM|aGW}_hAoXQeO_gc<6y?0snRL*x@)a*grQ%{pBN|*tUv}(#d0ULr z5bYdNA-Tw}J)vjE{9Jv)gXH5_gjAtGw!F)wC;UYDanyI5Odd~sNmLvMWU75n6SM@d7XNizPu(?EO=hkl9{`2n9&?)k{J&abq|mB$tev|q-Cw(t1#U`J4x1b z-GaHiUc9sS=9HZIYC^uFpa79lMa7jWYr8Ib-BlC8r-`DrEyN9k>81Yi&#-oweIv+pN@amGa-9ofadfndbPB*K#Ol2ztMRRtSHBB?a z+5W@$j0^W9PSL+wxsDlnBI6*%*f8|WcBh>;b=xZ}+Ahy(uFDgdSFp)WAJKC^OhdA^ zmwJKEIE^|OWKv-obFy~A)tQcvo(ay)j!}-$jzC<+SzKlgM$$Ayw8QlBBn>eIikyAr zI%L*DzIj41z%c@{Cy)HdtYkK4_KGQH%$c}Ei%IP3T*Zw1HWx}e@;io*U)znc1=kJz z$W4^Y>)65f%WD{U*}c+Ulz?L?;LlQDU_vA~{faGY^^EFJ2OXxK@IBOAyc^ym z_B}2K3%sOrun^J+3kxzjsC%*WBc6S>TQWRKBa;A{*b`1t$yxWYDOIxX%#?f^I-PZA zrVsmtLM$-0>uEx#%SEyV^~Zh~P

Qukk>W8{U#&zJ zxFUivCc`e-JMWWC_x<%-?j2+-*4v3wg=ILe7w_zi10A^2ATH)iG46W0Ug=*Ip9(%Z z_{hItGX}V{;QTXq4zT;hK3v+M0G?X#)Q0Cays$v-o0*C}i1AXlinFVi6?l%2Dm=$& z3#?~L<=BYm@#hFQ>evV0SR0*MZpSjOCR9!GnlCZ?^ZJ-8?~Gv$O%filPBpItSY(@u zhsjX)>`{<6M!`@EeGTGWT@55o| zO5PX_S?mpm;%)t<5yay$hWp@3;GYzyJzkOY-A0-%;BhR*#cs7XgpOTN)6GpS-qMFP zBFrT!uZ@D3s=R{rHLpk|3Qo!uM3@(7RtM2sV^-h%AdFcW@DH2#QGSI@-ELVeYsI== zU$h#PtJZ?uw(92Jctx*n&1S#XM;^W}rxEX1OSLzxrE2+AV;a*@qtaSxEw-%x1K!fZ ANB{r; diff --git a/__pycache__/eventGenerator.cpython-35.pyc b/__pycache__/eventGenerator.cpython-35.pyc deleted file mode 100644 index cf402e8409d36f6f70139b68d0acefe6d706c945..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3091 zcmZ8j-EJGl6+XM9__GovTZ*kTZkw^1#$qgza%|U$YP(kSSD}(Dh>DY{2#C?nkX(7W z%goHm=0dtsZwmA^dQqTHQJ@zE`UHF1D?dSjT=kq;N>)O0c4y{%bLRXX-mcZW^S}P{ zkF9Bd|H8FT4d*X#=zlu^0^kUr4hR=Q2aa%(&s{ij?YsbC0R}}lD#Bm_jwZk%L=nOg z9FAw@t62qS6Cg@3FUmM7II1{2m_Mq5EP|K>Sp_i#5>Yh}({KTWBM+npCzBv%K->Uv z6T~ctIS?Pfh3h(F+AR>bEo~mehsg7%^q+zF2*e!_KOdhJzX0(|5FdkJAnt-#fF53o z%zuS!i1&brLi(^wBvj@xU!K0POPga&6v(J|wJo3C3JTd)P=@quc zWyto~YRCsX@?*_-B-n1y=dAsjhk@_CkOLlsE3AjW=1?k`{)wCKl3}+gMY6;O2yJQ$ zrTrd(n|?g--ch*i)!l4*RrQjAjLbe)TB_`W1ODbvzBRv>;czon18$5|btiK^OQ+YR z_Ej)6K^(1kUb=PI4>U7z95U2OkZ|~mV#5i+x*=$!a$>o&=9#t(fT~%;V6|&wy1~P zmrTncr_c~}&wFVDORsp<_6BP-Fv5f3ko>>#HjZ$!O`EIl*Jb~tKa??*En zr(UCR94C?BYLq$c%z2fSh3xVqH0iUi#so$tYF<-@IJb=oe8U#kb2Q5Nind>I6>tm= z54oFkve7VoC3Qaz#XAr4Gb<9W^ba{K2m>=>W(;Ve>==X?nP_00vmeVAVE7qIP4tpY zZHDup7sVJ8>5WSnRhveTO=5d2kRc9scQ+#HgHh89ER3cLhWXy9D_oNN~ z_*ANp=l-#Wh)+ntCed4sP)0q|e}}yb();;>~-bmSNEz!e->szGG?@G)=n~E}Tz*nSnFQUleT5_}k@yVtxSI zttC5e?+|ePyE!;7!C4VbZo*l~V!rO8QWKJpsk;x`0d^>qWXQeIMUb13&`#iP8f>LZVmY)qY`rf9|sB!pLl0e>w!c}+d?>^rx_ zWM0zqTPs(Es(Mva>gB9RHc@xcAz6t`B9*GsqBQF5o8Dd#o{j^FB>Q+8&Zs&mV}r`=_zTv;sMaSBew N?p@6aQ=d*b{|5|OdKmx! diff --git a/__pycache__/fileMerger.cpython-35.pyc b/__pycache__/fileMerger.cpython-35.pyc deleted file mode 100644 index 269e0082c7088dba67574556f268ce3904dbc5ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2672 zcmZWrUvJyU5uYU~N|vQK$vJk?rVX!6E+%m;w$ zavMvzO_JA1-XQq{l0T#o9D~kH=roo(KO*_#TIbeMC*Y7+?&I3F{0YgQ(w`A7+_+8h zPR+xgPe|Ua`3@;K_9=bqkPd|Ezy(0;Esd(+<4Dz20aiadCMpReP$!M&dc+h6S5 z+uqsU4tAgH9|ZTdKmSF${V<+Z<3gLA;5XAa4|anmd6mv`)qbcZahmM}hgeQxofT%F z7F*k&{~@kkDpO5m8t2tuS`G(FPTSvc+4g#lz4S z6?zg^mD02BV`UPZmQ`BhJMG!KgK=ttswlGHut;+gOr}|tmYE7llLmzj)N!emF^~?1 zX{K0qq^hyfgZ71LYz$5gs&QO_C`f8kfvQXfpC&~%o#efs7@qI3l~}7F&4Z+vOp1Ka zwyW~OExR^cx*H`KY=^B_%4p1S%$$BY>-PI;UQVli?NR7Kx3Z0TDfHunLkk#zmSa6S^o#=vL)qcK69rdg*#Gt&otqM1$b@xh|hj%v$~a zV%PfTzfGxzG3q?Kz89lx=h1&?BEi_#9}m>Uvx~?45oAO(7j*m$oe({K`IP1kRYZq^ z4jnpi=v0t-TCcb~8vu$;tZvR-I)R8sCs-CFUU!%8wFS~aD>!a(EBWeA(ELARhUg%~9d8*W;jKEoEn1#(@7O~R5Nq+=i&%W3isl1q^iP=I~ zwAtdZ%BHE=LgSS>kGJ-J`|R1HE$*YQl^&t1%eQtlspq)1^fQk85(qiI=!&aiU0imq zIQkk^5>5<%R`G1$;dk>TQpZVh>G<6uNq?fh(Rq^oy2MfG(gGGiPlY>2W;{;ep-b}y z{e@@nzpEFP=(h9o%nz*&MA--=y^(xK#mWaEP9^l7hIqg zr+$I0r$WrJ-&~#tYtXGLf?5q7+5q&z=s)k$92;<|O(!k3HV3mphpTh~fLx15fO4i>pRxzgsBAjmqJ@@1bJ^nFhvF(S5M$}Ft_vd&;T^x;yJ%AU|yS(MM$>mXsS`QxK z-LQu%G`lt7){1Jd8r;u{B+kqOFiTn6TtK7=o4~LP_;e6@@o{Rt<4|XfJ7#dl%$%do ztY}*ihkhPMT9ww#08jU{+l?PD$ET)h$HX-Rh4yTX{oPZ zpM$^!Q(3RTI9ZRu-!_hPTB*>liYPH}daKsQJYlvp{vMECsnz6=S3*Y)!*-D|Dsxf7 zcCL=z^L4y3l0&1fvyw9$TPMrwOf9p<3A3voWadjOn42Kv@}zz2bi@sD2eWp~={PsV znz#E?m&pCn)2qD-NfiHgbJ-pji6tP4U^)A_F6v-lqqPjW^O zvC+4opt;DHAZofZ)y@c7?s|!-ssC9o*$Z4h?G-1f>fcPj4 ge>Xf=G~KK4bxrv7x9Kjqj%a?c+Ua&~bUGdJJt2#dg8%>k diff --git a/__pycache__/psiCalculator.cpython-35.pyc b/__pycache__/psiCalculator.cpython-35.pyc deleted file mode 100644 index b7e35d45c0cfe1b98d1e80f75ac9c5a2e7d6f499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4719 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 Ct;3xF diff --git a/__pycache__/psiPerGene.cpython-35.pyc b/__pycache__/psiPerGene.cpython-35.pyc deleted file mode 100644 index d92618821f91da1943b65f8b7c5ff3c6464d456e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4463 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 XNBZjg&s(3*)j4s;#?tcA>XP$6-hO~- diff --git a/suppa/__pycache__/__init__.cpython-35.pyc b/suppa/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index ae83a395b51ca782e348043e83de066d4e2fdc5f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 203 zcmWgR<>jjDITRVfz`*brh~a<{$Z`PUVlE(&!oUy(BpDfkHJPeRxSWep6H8K46!P;F zLP}E=+)|Si3=I_wjjRmKtxQc7j0_A-xVRh=OG`5Hi>wsV6H{}z{4^PFvB$@!V>gQx8 g>Bq-s=4F<|$LkeT-r}&y%}*)KNws4GITDB&0QyrjO#lD@ diff --git a/suppa/__pycache__/cluster_tools.cpython-35.pyc b/suppa/__pycache__/cluster_tools.cpython-35.pyc deleted file mode 100644 index 114eceb14b068f38b54b01e28393b3214ddc686d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8724 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 diff --git a/suppa/__pycache__/diff_tools.cpython-35.pyc b/suppa/__pycache__/diff_tools.cpython-35.pyc deleted file mode 100644 index ce97843511d200bd9f1ba8c96479be4800746a08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20870 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 diff --git a/suppa/__pycache__/optics.cpython-35.pyc b/suppa/__pycache__/optics.cpython-35.pyc deleted file mode 100644 index 871f6ff933277f0fd507e40ca09d6f3240551b11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6338 zcmbtYOLH7o6~4E7-kQ-PvSlfD62-QtObC(#2~XoV$dy19r5F^-WD3{Rc)BIEJkve8 z-IGXz#exJ9sBBXF3W~~-4Lhh}N!YRI9YwM5A7GIM#rK`tJr7%{P%u*8zJ2>X&OPTl z-#L9(8jae|KK#>L|K3#UA8P97qJ9%se2T)uzg9h^TI0G_EuFVJs^#YOf@&3{?xr*_ln9ZNmEIhDrhPzuOdwqX{vJ7-DdS6L{K|TotBL6 z4ZD7q&-rgG=r&q>h$v#U9FFxI&PL(#^(mYzjJ4jw9#F3+uPWV2e6`!GrN!G(5GGyD z%pdO#E-nzih~j}(50q-7;z$Jx*%n!pudtkbh2^*fcXVkx3gg5KyGdl$_i%;lUeNc$ zI6(W(Yt3Tn1YTO3w53khOC95-)q#n+ejNK=(@hJp-`g_<2w{pSeydCkw@+W%+V{h# zA9UlbVeFfD>u}f!d&3~!>PG#62|HW6Ke~PU)vaD|Zz~!k=(jmINh|Gk5C%!R{SxMg zIgxUz+Ww8^MG2dEmo7EHAD5*@L>o6yNt8O2?H@YoU9C=?yhW?5#g!IU9Tr4mu3BY3 zJQScBJzBpN#7QUY`s;l^If%T+)I;TjgS6N&rgI|uPD{NY?DY22LKvBTvuLUiBrOhT zw^VmheJ?F|m{qi6i#hhFu#rps7*BBpg>s+JPv{jV-*4VwXS`uFP=q2hTI z$|-4A+pF%5R;+a&?cUYwiXZP|E1$!IMfiA^dyZP!Z8|%n%5xigFRX9uH6hj|^fMPx zG_@6xkeb$hyKVe|L5cQQ0Ht%i=dYS&!ZPgi{dPO8wcGv38}?YQx7$ahep_)Z5WNBJMDd^)@V$1iH+RH8a%iLD53l#nV9<_p> zBKpjd87Exkgexe33Cv0B$Pgew%nCF*soU=yi<6A%J6=c*leiy~HX`*zaX*1}@GtEBz*T{bL|T~_8IKsr#2++##AXewNXmd{4}W3ls*L5! z93w1W*)d!+{637p}BUU?W&-fzi7?2?1$|knoM2 z`wYex`uh#$6k{rcvbrv*hC4&{tGSjQrTb>tJVV*mSv<=^cvaL+K`psX96)N~1()%5 zgv;`(u9xeTdeyMCi);L&fp6l92PpnGUWKobRFMnTBufL?&MB`hb);?$<;_bS9Tt?g zDD|51mVo;w($X7}>~zJ|AOi1{X&YC}t;5)W|8yz`Ot1w;&sf>DZe4>jv@JZ-#eNXB zyO!VEaWL{>*eYg|p61J}eTBtDbD}gV_jkA~f+f`&Em#R3XK#v0^oXe6N9FiR2I5%_Z(zc%Y zIrR7kPDJ@Z*U#qri~VFcn5Kf9tC783L0?m5L7z?MhT%BpP0PrQeB}LkOgw{=(^6Yz z|2+n0Y3w4>*oI!yqsGko={B>iwcJ z0mEg+y+RY@-f<`ew^$HyL_w{tVKN{rn-XT*Z5DSPGD^>wfZ{Au9O5!F!TCw(#Bj(l zZ3}QQGaxADDsHJ})LBApLe7T4>d&}xYcz9hbR**-ZMYyS~5#B>bhET}Rp_KZHKN9WI! zb0(Fd<-~eS0AY*wCD<_~cNEO=f#e&6zr?>hC*rQgivA`ZGDTm@6b&sC0Fu1}4_4`% zORM{c5z;5 zG)P^R5%tz4y8jCo;)azoT6%1m8D+B9HoG&1G1Uj3SPH?`5%X+F1d$;0@hdJ1k%Y3d z^CmpFf^mik3cu0&(c8XxSsprrfgg^2cP#e=qR8>bzWz518FS;Jo(MheF(z`tk}+O{ z<`Kp5+wwUkAN&xHhQD>U!>>$cIEdNe$=nN0ASB5-ElR*gA^@9Ll)0-ONDH_U?#o?D zPknSQdx5>*$1d|n^uwz=82uQ+h)ZG9vt1c`goraR(xSl}L0`vstD;%x{1ffDD__nn zYIBJ*QByR}b0+a&`B*CR@f8%!k_}kjVgt>R7GvM{V#B3drO` zepD8oEM3$K;Mzr$qxo5py1CO49Ajg>jaC9lvRDnQA(S1ztl0zydp)b5eGO?E)C70F zfG!D+6<`=VyXss5KhLt#u+gTWX0evrGWQ@BSUCQ8MhG%>tjFw)!c5P#Q`uBNK)|yM^tC-mG zkc-owv}mGX=-K#n1+P*!K8X>;5-%DiY4IHsBz{`lLne1%ZgS|iSzKrF9TYfjL%2)b zK{OCPYgWW-T7_X$>&M40*G|N zecwWaF-!1EOhlbTsM4nLm+`7OXU)Hqr~b)-@#BN2=cSdb2?uzwKj@eaj(Ou$2dz?a z5X5cVL;pD8U7iQ6vfOdJTSN{~Er!GX;KVdI;dfD_)xBYe6Y!`P8>Srg^O&lY e(Pu4+^96eZc!L{}s8h!`F8)f3?(!SUTmJ$0xTA{z diff --git a/suppa/__pycache__/tools.cpython-35.pyc b/suppa/__pycache__/tools.cpython-35.pyc deleted file mode 100644 index a6149d977f45be6b8f9397a452116b6ebc07e34c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18099 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 diff --git a/suppa/__pycache__/var_event.cpython-35.pyc b/suppa/__pycache__/var_event.cpython-35.pyc deleted file mode 100644 index 8648364b6c2ea3e508901ee3ece33bfc39c4a3fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23013 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 From bc81efb97730c637fac9ffedde7f568c41312574 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 17:05:18 +0100 Subject: [PATCH 03/14] Fix suppa install --- setup.py | 38 +++++++++++++++++++++++++++----------- suppa.py => suppa2 | 0 2 files changed, 27 insertions(+), 11 deletions(-) mode change 100644 => 100755 setup.py rename suppa.py => suppa2 (100%) diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index dd7988c..40a6cde --- a/setup.py +++ b/setup.py @@ -1,14 +1,30 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -from distutils.core import setup +from setuptools import setup, find_packages -setup(name='SUPPA', - version='2.3', - description='SUPPA2: Fast quantification of differential splicing', - url='https://github.com/comprna/SUPPA', - scripts=['suppa.py'], - author="comprna", - packages=['suppa'], - install_requires=['scipy', 'numpy', 'pandas', 'statsmodels', 'sklearn'], - python_requires='>=3', +setup( + name='SUPPA', + packages=find_packages(), + scripts=['suppa2'], + version='2.3', + description='A tool to study splicing across multiple conditions at high speed and accuracy.', + author='GP Alamancos', + author_email='eduardo.eyras@upf.edu', + license='MIT', + url='https://github.com/comprna/SUPPA', + download_url='https://github.com/comprna/SUPPA/archive/v2.3.tar.gz', + keywords=['alternative', 'splicing', 'analysis', 'transcriptomics'], + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Topic :: Scientific/Engineering :: Bio-Informatics', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: MIT License', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 3.5'], + install_requires=['scipy>=0.15.1', + 'numpy>=1.11.0', + 'pandas>=0.18.0', + 'statsmodels>=0.6.1', + 'scikit-learn>=0.16.1'], + python_requires='>=3', ) diff --git a/suppa.py b/suppa2 similarity index 100% rename from suppa.py rename to suppa2 From 4b088fc678542c5b23c428792f5fffb72c23e906 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 17:09:30 +0100 Subject: [PATCH 04/14] Fix suppa install --- setup.py | 2 +- suppa2 => suppa_run.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename suppa2 => suppa_run.py (100%) diff --git a/setup.py b/setup.py index 40a6cde..2048ef7 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='SUPPA', packages=find_packages(), - scripts=['suppa2'], + scripts=['suppa_run.py'], version='2.3', description='A tool to study splicing across multiple conditions at high speed and accuracy.', author='GP Alamancos', diff --git a/suppa2 b/suppa_run.py similarity index 100% rename from suppa2 rename to suppa_run.py From fc0816d74b8a3540237896a870a91cb09aa62b84 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 17:10:52 +0100 Subject: [PATCH 05/14] Fix suppa install --- setup.py | 2 +- suppa_run.py => suppa2.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename suppa_run.py => suppa2.py (100%) diff --git a/setup.py b/setup.py index 2048ef7..0b6af45 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='SUPPA', packages=find_packages(), - scripts=['suppa_run.py'], + scripts=['suppa2.py'], version='2.3', description='A tool to study splicing across multiple conditions at high speed and accuracy.', author='GP Alamancos', diff --git a/suppa_run.py b/suppa2.py similarity index 100% rename from suppa_run.py rename to suppa2.py From 6aa4d65d959055ffea2ad85112725fd3bf7f7199 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Sun, 24 Feb 2019 18:29:47 +0100 Subject: [PATCH 06/14] Add scripts/format_Ensembl_ids.R --- suppa/multipleFieldSelection.py => multipleFieldSelection.py | 0 setup.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename suppa/multipleFieldSelection.py => multipleFieldSelection.py (100%) diff --git a/suppa/multipleFieldSelection.py b/multipleFieldSelection.py similarity index 100% rename from suppa/multipleFieldSelection.py rename to multipleFieldSelection.py diff --git a/setup.py b/setup.py index 0b6af45..cdcb5c7 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='SUPPA', packages=find_packages(), - scripts=['suppa2.py'], + scripts=['suppa2.py', 'multipleFieldSelection.py', 'scripts/format_Ensembl_ids.R'], version='2.3', description='A tool to study splicing across multiple conditions at high speed and accuracy.', author='GP Alamancos', From edf88d9bb5fe2b67e085795cffeed5f1300677cc Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 10:04:16 +0100 Subject: [PATCH 07/14] Add doc --- README.md | 48 ++++++++++++++----- ...ano_MA_plot.R => suppa2_Volcano_MA_plot.R} | 2 + ...embl_ids.R => suppa2_format_Ensembl_ids.R} | 3 +- ..._format_unique_fasta_RefSeq_annotation.py} | 2 + ...nt.py => suppa2_generate_boxplot_event.py} | 4 +- .../suppa2_multipleFieldSelection.py | 2 + scripts/{split_file.R => suppa2_split_file.R} | 2 +- setup.py | 10 +++- 8 files changed, 57 insertions(+), 16 deletions(-) rename scripts/{Volcano_MA_plot.R => suppa2_Volcano_MA_plot.R} (99%) mode change 100644 => 100755 rename scripts/{format_Ensembl_ids.R => suppa2_format_Ensembl_ids.R} (96%) rename scripts/{format_unique_fasta_RefSeq_annotation.py => suppa2_format_unique_fasta_RefSeq_annotation.py} (99%) rename scripts/{generate_boxplot_event.py => suppa2_generate_boxplot_event.py} (99%) mode change 100644 => 100755 rename multipleFieldSelection.py => scripts/suppa2_multipleFieldSelection.py (99%) mode change 100644 => 100755 rename scripts/{split_file.R => suppa2_split_file.R} (98%) diff --git a/README.md b/README.md index da3da1d..dedd848 100644 --- a/README.md +++ b/README.md @@ -72,10 +72,34 @@ SUPPA has been developed in Python 3.4. If necessary, to install python3 we recommend to download from the official site https://www.python.org/downloads/ the corresponding version for your OS. +## From the tar.gz archive + +Uncompress the archive using: +``` +tar xvzf SUPPA-2.3.tar.gz +cd SUPPA +``` + +As root/administrator, you can install with: +``` +python3 setup.py install +``` +or as a non-privilegied user for a user specific install: +``` +python3 setup.py install --user +``` +in this case, on a unix-like environment, the executable are installed by default in `~/.local/bin`. You can add this path to the shell search path with (Bash shell): + +``` +if ! grep -q 'PATH.*~/\.local/bin' ~/.bashrc ; then echo 'export PATH=$PATH:~/.local/bin' >>~/.bashrc; fi +``` + +## Using pip + A installation using pip is available using the next command: ``` -pip install SUPPA==2.2.1 +pip install SUPPA==2.3 ``` By default SUPPA is installed into the Python package library directory. The following command can be executed to obtain the directory location: @@ -85,6 +109,8 @@ pip show SUPPA SUPPA is ready to use. Once downloaded, it can be used directly from the command line by specifying the absolute path to the SUPPA executable (suppa.py). +## Using bioconda + Another option is via bioconda (thanks to Devon Ryan) ``` @@ -98,7 +124,7 @@ conda install -c bioconda suppa SUPPA works with a command/subcommand structure: ``` -python3.4 suppa.py subcommand options +python3 suppa2.py subcommand options ``` where the subcommand can be one of these five: @@ -165,7 +191,7 @@ The *generateEvents* operation uses the lines where the feature (column 3) is "e To generate the events from the GTF file one has to run the following command: ``` -python3.4 suppa.py generateEvents [options] +python3 suppa2.py generateEvents [options] ``` List of options available: @@ -202,13 +228,13 @@ List of options available: The command line to generate local AS events will be of the form: ``` -python3.4 suppa.py generateEvents -i -o -f ioe -e +python3 suppa2.py generateEvents -i -o -f ioe -e ``` The command to generate the transcript "events" would be of the form: ``` -python3.4 suppa.py generateEvents -i -o -f ioi +python3 suppa2.py generateEvents -i -o -f ioi ``` ## Output files @@ -402,7 +428,7 @@ python3.4 suppa.py psiPerIsoform -g -e -o --expression-file -o +python3 suppa2.py psiPerEvent --ioe-file --expression-file -o ``` ### **Output files** ### @@ -456,7 +482,7 @@ ENSG00000000419.12;SE:chr20:50940933-50941105:50941209-50942031:- 0.023022 Transcript expression files used with SUPPA typically come from calculations with multiple samples. To facilitate the generation of a single file with all the transcript expression values for all samples, SUPPA distribution includes a program to combine multiple simple transcript expression files into one single file: ``` -python3.4 suppa.py joinFiles [options] +python3 suppa2.py joinFiles [options] ``` @@ -564,7 +590,7 @@ List of options available: An example of the usage of the program with transcripts is, indicating that replicates are paired (-pa), to apply a multple testing correction (-gc) and perform pairwise comparison between all conditions (-c): ``` -python3.4 suppa.py diffSplice --method --input --psi --expression-file --area <1000> --lower-bound <0.05> -pa -gc -c -o +python3 suppa2.py diffSplice --method --input --psi --expression-file --area <1000> --lower-bound <0.05> -pa -gc -c -o ``` ### **Differential splicing with local events** ### @@ -572,7 +598,7 @@ python3.4 suppa.py diffSplice --method --input --psi --input --psi --expression-file --area <1000> --lower-bound <0.05> -gc -o +python3 suppa2.py diffSplice --method --input --psi --expression-file --area <1000> --lower-bound <0.05> -gc -o ``` ### **Output files** ### @@ -661,7 +687,7 @@ event3 Date: Mon, 25 Feb 2019 10:06:45 +0100 Subject: [PATCH 08/14] Add doc --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dedd848..dd4f282 100644 --- a/README.md +++ b/README.md @@ -403,7 +403,7 @@ transcript3 At the moment the PSI per transcript isoform is calculated in the following way: ``` -python3.4 suppa.py psiPerIsoform [options] +python3 suppa2.py psiPerIsoform [options] ``` List of options available: @@ -420,7 +420,7 @@ List of options available: An example of the usage of the program is: ``` -python3.4 suppa.py psiPerIsoform -g -e -o +python3 suppa2.py psiPerIsoform -g -e -o ``` ### **PSI per local event** ### @@ -500,7 +500,7 @@ where the options are: We show below an example of the usage of the program for reading multiple output files from Sailfish to join together the 3rd column, given that all files have in the first column the transcript ids (which are kept for the output): ``` -python3.4 suppa.py joinFiles -f tpm -i sample1.tpm sample2.tpm sample3.tpm -o all_samples_tpms +python3 suppa2.py joinFiles -f tpm -i sample1.tpm sample2.tpm sample3.tpm -o all_samples_tpms ``` The output will look like an expression file with multiple files as described above. @@ -547,7 +547,7 @@ where the expression values are given in TPM units. ### **Command and options** ### To calculate the dpsi from the *ioe*, *psi* and the *expression file* one has to run the following command: ``` -python3.4 suppa.py diffSplice [options] +python3 suppa2.py diffSplice [options] ``` List of options available: @@ -719,7 +719,7 @@ List of options available: An example of the usage of the program is: ``` -python3.4 suppa.py clusterEvents --dpsi --psivec --sig-threshold <0.05> --eps <0.05> --min-pts <20> --groups <1-3,4-6> -o +python3 suppa2.py clusterEvents --dpsi --psivec --sig-threshold <0.05> --eps <0.05> --min-pts <20> --groups <1-3,4-6> -o ``` From ea9126df40de536139c021d8ea64bb3b3f424aec Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 10:13:52 +0100 Subject: [PATCH 09/14] Add doc --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index dd4f282..58b800d 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,9 @@ Read our [short SUPPA tutorial on an example dataset](https://github.com/comprna * [Overview](#overview) * [Installation](#installation) + * [From the tar.gz archive](#from-the-tar-gz-archive) + * [Using pip](#using-pip) + * [Using bioconda](#using-bioconda) * [Command and subcommand structure](#command-and-subcommand-structure) * [Generation of transcript events and local alternative splicing events](#generation-of-transcript-events-and-local-alternative-splicing-events) * [Input files](#input-files) From b91623ecc4f595f55c1940efde9a96874c74ba82 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 10:17:43 +0100 Subject: [PATCH 10/14] Add doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58b800d..84a61ad 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Read our [short SUPPA tutorial on an example dataset](https://github.com/comprna * [Overview](#overview) * [Installation](#installation) - * [From the tar.gz archive](#from-the-tar-gz-archive) + * [From the tar.gz archive](#from-the-targz-archive) * [Using pip](#using-pip) * [Using bioconda](#using-bioconda) * [Command and subcommand structure](#command-and-subcommand-structure) From 738d3a9c387b72d24d9cde64f11da925ef2908df Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 16:24:10 +0100 Subject: [PATCH 11/14] Workaround setuptools bug --- scripts/suppa2_split_file.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/suppa2_split_file.R b/scripts/suppa2_split_file.R index 37c6a23..88dea15 100755 --- a/scripts/suppa2_split_file.R +++ b/scripts/suppa2_split_file.R @@ -7,6 +7,10 @@ #[4] Fourth argument: output file of the first condition #[5] Fifth argument: output file of the second condition +## bug in setuptools, this script is recognized as python if not included +## bugs #355, #1178 +data.frame(a="")$a + # Parse command line arguments print("Parsing samples...") CHARACTER_command_args <- commandArgs(trailingOnly=TRUE) From 65d6a91f98c2828395a3a234fbec5b174c645a51 Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 18:40:18 +0100 Subject: [PATCH 12/14] Fix number of columns --- suppa/psiCalculator.py | 2 +- suppa/tools.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/suppa/psiCalculator.py b/suppa/psiCalculator.py index 5cd9f9e..54ed758 100644 --- a/suppa/psiCalculator.py +++ b/suppa/psiCalculator.py @@ -158,7 +158,7 @@ def main(): writer = Writer.getWriter("PSI") logger.info("Generating output %s" % (output_file + ".psi")) writer.openFile(output_file) - writer.writeLine("\t".join(col_ids), False) + writer.writeLine("\t".join(["Name"] + col_ids), False) for key, value in sorted(psi_dictionary.items()): logger.debug("Calculating psi for %s" % key) psi_line = PsiWriter.lineGenerator(key, value, col_ids) diff --git a/suppa/tools.py b/suppa/tools.py index 20b705f..4921465 100644 --- a/suppa/tools.py +++ b/suppa/tools.py @@ -376,9 +376,9 @@ def readLine(self, header = True): fields = line.rstrip("\n").split("\t") if lineNumber == 0 and header: #Skip the header line #Calculating the number of fields required - min_fields = (len(line.rstrip("\n").split("\t")) + 1) + min_fields = len(fields) #Storing column_id for the expression fields - colIds = fields + colIds = fields[1:] continue if line.startswith('#'): logger.debug("Line %i starts with #. Skipping line..." % ( From 64a3674c9925e06d3de65e96bdbd8e20dd49d4fc Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 18:52:32 +0100 Subject: [PATCH 13/14] Fix names in file_split --- scripts/suppa2_split_file.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/suppa2_split_file.R b/scripts/suppa2_split_file.R index 88dea15..2b84ea8 100755 --- a/scripts/suppa2_split_file.R +++ b/scripts/suppa2_split_file.R @@ -17,7 +17,7 @@ CHARACTER_command_args <- commandArgs(trailingOnly=TRUE) #Load the input file print(paste0("Loading ",CHARACTER_command_args[1],"...")) -input_file <- read.table(CHARACTER_command_args[1],header=TRUE) +input_file <- read.table(CHARACTER_command_args[1],header=TRUE, check.names=FALSE) #Load the list of samples of the first condition first_condition <- unlist(strsplit(CHARACTER_command_args[2],",")) From 8a882fd50ee94be19b131c185f3bac6dbb6231ee Mon Sep 17 00:00:00 2001 From: Anthony Piron Date: Mon, 25 Feb 2019 19:01:23 +0100 Subject: [PATCH 14/14] Fix names in file_split --- scripts/suppa2_split_file.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/suppa2_split_file.R b/scripts/suppa2_split_file.R index 2b84ea8..ce78e1a 100755 --- a/scripts/suppa2_split_file.R +++ b/scripts/suppa2_split_file.R @@ -17,7 +17,7 @@ CHARACTER_command_args <- commandArgs(trailingOnly=TRUE) #Load the input file print(paste0("Loading ",CHARACTER_command_args[1],"...")) -input_file <- read.table(CHARACTER_command_args[1],header=TRUE, check.names=FALSE) +input_file <- read.table(CHARACTER_command_args[1],row.names=1,header=TRUE, check.names=FALSE) #Load the list of samples of the first condition first_condition <- unlist(strsplit(CHARACTER_command_args[2],","))