File: pyOpenMS.html

package info (click to toggle)
openms 1.11.1-5
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 436,688 kB
  • ctags: 150,907
  • sloc: cpp: 387,126; xml: 71,547; python: 7,764; ansic: 2,626; php: 2,499; sql: 737; ruby: 342; sh: 325; makefile: 128
file content (173 lines) | stat: -rw-r--r-- 10,970 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<HTML>
<HEAD>
<TITLE>pyOpenMS (Python bindings)</TITLE>
<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
<LINK HREF="style_ini.css" REL="stylesheet" TYPE="text/css">
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<A href="index.html">Home</A> &nbsp;&middot;
<A href="classes.html">Classes</A> &nbsp;&middot;
<A href="annotated.html">Annotated Classes</A> &nbsp;&middot;
<A href="modules.html">Modules</A> &nbsp;&middot;
<A href="functions_func.html">Members</A> &nbsp;&middot;
<A href="namespaces.html">Namespaces</A> &nbsp;&middot;
<A href="pages.html">Related Pages</A>
<HR style="height:1px; border:none; border-top:1px solid #c0c0c0;">
<!-- Generated by Doxygen 1.8.5 -->
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">pyOpenMS (Python bindings) </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1 style="margin-top:40px; border-top:4px solid grey; text-align:left;">Introduction</h1>
<p>PyOpenMS offers Python bindings to a large part of the OpenMS API.</p>
<h1 style="margin-top:40px; border-top:4px solid grey; text-align:left;">Build Instructions</h1>
<p>In order to configure and build pyOpenMS successfully, you will need to install the following :</p>
<ol>
<li>
<p class="startli">Install python (preferably, 2.7 but it may run also run with Python 2.6) </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">On windows: you need the 64 bit C++ compiler from Visual Studio 2008. This is important, else you get a different clib than python 2.7 is built with, and pyopenms will crash on import. </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Install setuptools, see: <a href="https://pypi.python.org/pypi/setuptools">https://pypi.python.org/pypi/setuptools</a> </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Install pip and using it, install other required Python modules</p>
<div class="fragment"><div class="line">$ easy_install pip</div>
<div class="line">$ pip install autowrap</div>
<div class="line">$ pip install nose</div>
</div><!-- fragment --><p>If Cython doesn't get installed, install it with </p>
<div class="fragment"><div class="line">$ easy_install cython</div>
</div><!-- fragment --><p>Note that when using pip without root permissions, you have to add a path prefix: &ndash;install-option="--prefix=/path/to/local/python/" </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Install numpy:</p>
<ul>
<li>on debian/ubuntu, install the package "python-numpy"</li>
<li>on 64 bit win 7: get it from <a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy">http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy</a> </li>
</ul>
<p class="endli"></p>
</li>
<li>
<p class="startli">Configure OpenMS with pyOpenMS: execute cmake as usual, but with parameters "-D PYOPENMS=ON". </p>
<p>On windows add: "-D CMAKE_BUILD_TYPE=Release" as the standard python27.dll is built in release mode. </p>
<p></p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Build pyOpenMS (now there should be pyopenms specific build targets):</p>
<div class="fragment"><div class="line">$ make pyopenms</div>
</div><!-- fragment --><p>on linux: ensure that the libOpenMS.so is in your $LD_LIBRARY_PATH (it needs to be accessible for Python) </p>
<p class="endli"></p>
</li>
<li>
<p class="startli">Run the Python specific tests to make sure that everything went well</p>
<div class="fragment"><div class="line">$ cd pyOpenMS</div>
<div class="line">$ run_nose.py</div>
</div><!-- fragment --><p>run mem leak test:</p>
<div class="fragment"><div class="line">$ run_memleaks.py</div>
</div><!-- fragment --> <p class="endli"></p>
</li>
<li>
<p class="startli">Optionally: if you want to install locally:</p>
<div class="fragment"><div class="line">$ python setup.py install</div>
</div><!-- fragment --><p> If you want to build Python installers:</p>
<div class="fragment"><div class="line">$ make pyopenms_bdist_egg</div>
</div><!-- fragment --><p>or</p>
<div class="fragment"><div class="line">$ make pyopenms_bdist</div>
</div><!-- fragment --><p>you find the built installer files in pyOpenMS/dist </p>
<p class="endli"></p>
</li>
</ol>
<h1 style="margin-top:40px; border-top:4px solid grey; text-align:left;">Wrapping Workflow and wrapping new Classes</h1>
<h2 style="margin-top:40px; border-top:4px solid grey; text-align:left;">How pyOpenMS wraps Python classes</h2>
<p>General concept of how the wrapping is done:</p>
<ul>
<li>Step 1: The author declares which classes and which functions of these classes s/he wants to wrap (expose to Python). This is done by writing the function declaration in a file in the pxds/ folder.</li>
<li>Step 2: The Python tool "autowrap" (developed for this project) creates the wrapping code automatically from the function declaration - see <a href="https://github.com/uweschmitt/autowrap">https://github.com/uweschmitt/autowrap</a> for an explanation of the autowrap tool. Since not all code can be wrapped automatically, also manual code can be written in the addons/ folder. Autowrap will create an output file at pyopenms/pyopenms.pyx</li>
<li>Step 3: Cython translates the pyopenms/pyopenms.pyx to Cpp code at pyopenms/pyopenms.cpp</li>
<li>Step 4: A compiler compiles the Cpp code to a Python module which is then importable in Python with "import pyopenms"</li>
</ul>
<p>Maintaining existing wrappers: If the C++ API is changed, then pyOpenMS will not build any more. Thus, find the corresponding file in the pyOpenMS/pxds/ folder and adjust the function declaration accordingly.</p>
<h2 style="margin-top:40px; border-top:4px solid grey; text-align:left;">How to wrap new classes</h2>
<p>To wrap a new OpenMS class: Create a new "pxd" file in the folder "./pxds". As a small example, look at the CVTerm.pxd to get you started. Start with the following structure:</p>
<div class="fragment"><div class="line">from xxx cimport *</div>
<div class="line">cdef <span class="keyword">extern</span> from <span class="stringliteral">&quot;&lt;OpenMS/path/to/header.h&gt;&quot;</span> <span class="keyword">namespace </span>&quot;OpenMS&quot;:</div>
<div class="line"></div>
<div class="line">    cdef cppclass ClassName(DefaultParamHandler):</div>
<div class="line"><span class="preprocessor">        # wrap-inherits:</span></div>
<div class="line"><span class="preprocessor"></span><span class="preprocessor">        #    DefaultParamHandler</span></div>
<div class="line"><span class="preprocessor"></span></div>
<div class="line">        ClassName() nogil except +</div>
<div class="line">        ClassName(ClassName) nogil except +</div>
</div><!-- fragment --><ul>
<li>make sure to use "ClassName:" instead of "ClassName(DefaultParamHandler)" to wrap a class that does not inherit from another class and also remove the two comments below that line.</li>
<li>always use "cimport" and not Python "import"</li>
<li>always add default constructor AND copy constructor to the code (note that the C++ compiler will add a default copy constructur to any class, so there is always one if it is not declared, see <a href="http://www.cplusplus.com/articles/y8hv0pDG/">http://www.cplusplus.com/articles/y8hv0pDG/</a> "The
  implicit copy constructor does a member-wise copy of the source object.")</li>
<li>to expose a function to Python, copy the signature to your pxd file, e.g. "DataValue getValue()" and make sure you "cimport" all corresponding classes. Replace std::vector with vector from libcpp.vector (see for example PepXMLFile.pxd)</li>
<li>Remember to include a copy constructor (even if none was declared in the C++ header file) since Cython will need it for certain oprations. Otherwise you might see error messages like "item0.inst = shared_ptr[_ClassName](new _ClassNAme(deref(it_terms))) Call with wrong number of arguments"</li>
</ul>
<p>Further considerations and limitations:</p>
<ul>
<li>Inheritance: there are some limitations, see for example Precursor.pxd</li>
<li>Reference: arguments by reference may be copied under some circumstances. For example, if they are in an array then not the original argument is handed back, so comparisons might fail. Also, simple Python types like int, float etc cannot be passed by reference.</li>
<li>operator+=: see for example AASequence.iadd in AASequence.pxd</li>
<li>operator==, !=, &lt;=, &lt;, &gt;=, &gt; are wrapped automatically</li>
<li>Iterators: some limitations apply, see MSExperiment.pxd for an example</li>
<li>copy-constructor becomes __copy__ in Python</li>
<li>shared pointers: is handled automatically, check DataAccessHelper using shared_ptr[Spectrum]. Use "from smart_ptr cimport shared_ptr" as import statement</li>
</ul>
<p>These hints can be given to autowrap (also check the autowrap documentation):</p>
<ul>
<li>wrap-ignore: is a hint for autowrap to not wrap the function (but the declaration might still be important for Cython to know about)</li>
<li>wrap-as - see for example AASequence ":"</li>
<li>wrap-iter-begin, wrap-iter-end (see ConsensusMap.pxd)</li>
<li>wrap-instances - for templated classes (see MSSpectrum.pxd)</li>
<li>wrap-attach: enums, static methods (see for example VersionInfo.pxd)</li>
<li>wrap-upper-limit:size or size() (see MSSpectrum.pxd)</li>
</ul>
<h3 style="margin-top:40px; border-top:4px solid grey; text-align:left;">Wrapping code yourself in ./addons </h3>
<p>Not all code can be wrapped automatically (yet). Place a file with the same (!) name in the addons filder (e.g. myClass.px in pxds/ and myClass.pyx in addons) and leave two lines empty on the top (this is important). Start with 4 spaces of indent and write your additional wrapper functions, adding a wrap-ignore comment to the pxd file. For some examples, look into the addons folder:</p>
<ul>
<li>IDRipper.pyx<ul>
<li>for a reference for both input and output of a complex STL construct (map&lt; String, pair&lt;vector&lt;&gt;, vector&lt;&gt; &gt; )</li>
</ul>
</li>
<li>MSQuantifications.pyx<ul>
<li>for a vector&lt; vector&lt; pair &lt;String,double &gt; &gt; &gt; as input in registerExperiment</li>
<li>for a map&lt; String, Ratio&gt; in getRatios to get returned</li>
</ul>
</li>
<li>QcMLFile.pyx<ul>
<li>for a map&lt; String, map&lt; String,String&gt; &gt; as input</li>
</ul>
</li>
<li>SequestInfile.pyx<ul>
<li>for a map&lt; String, vector&lt;String&gt; &gt; to get returned</li>
</ul>
</li>
<li>Attachment.pyx<ul>
<li>for a vector&lt; vector&lt;String&gt; &gt; to get returned</li>
</ul>
</li>
</ul>
<p>Make sure that you _always_ declare your objects (all C++ and all Cython objects need to be declared) using cdef Type name. Otherwise you get "Cannot
convert ... to Python object" errors. </p>
</div></div><!-- contents -->
<HR style="height:1px; border:none; border-top:1px solid #c0c0c0;">
<TABLE width="100%" border="0">
<TR>
<TD><font color="#c0c0c0">OpenMS / TOPP release 1.11.1</font></TD>
<TD align="right"><font color="#c0c0c0">Documentation generated on Thu Nov 14 2013 11:19:25 using doxygen 1.8.5</font></TD>
</TR>
</TABLE>
</BODY>
</HTML>