pythonPackages.pyhepmc: init at 0.5.0

This commit is contained in:
Dmitry Kalinkin 2017-01-09 03:30:05 -05:00
parent fa8afc05c0
commit e60805061b
No known key found for this signature in database
GPG Key ID: 5157B3EC8B2CA333
3 changed files with 259 additions and 0 deletions

View File

@ -0,0 +1,204 @@
# HG changeset patch
# User Lukas Heinrich <lukas.heinrich@gmail.com>
# Date 1430606843 14400
# Node ID 325f89b7b72922e9add9ca9dd0f7ca4a6c83bf00
# Parent e4fd953257e0d38511f2177de7ffaef662358af2
add incoming/outgoing generators for GenVertex
diff --git a/hepmc/generators.i b/hepmc/generators.i
new file mode 100644
--- /dev/null
+++ b/hepmc/generators.i
@@ -0,0 +1,171 @@
+/*!
+ * \file generators.i
+ * \author Seth R. Johnson
+ * \brief Define generator/iterator for any type
+
+Example:
+\code
+ SETUP_GENERATOR( std::vector<Cell>::const_iterator )
+ ADD_GENERATOR( Mesh, cells,
+ std::vector<Cell>::const_iterator, Cell, beginCells, endCells)
+\endcode
+would be a method to add a \c cells generator method method to the Python class
+\c Mesh, when the C++ class \c Mesh has a \c std::vector<Cell> accessed through
+methods \c beginCells and \c endCells.
+
+The macro \c ADD_GENERATOR_P would be if the underlying storage were \c
+std::vector<Cell*> instead.
+
+Alternatively, for containers of regular objects that provide \c begin(), \c end(), and \c const_iterator, you can use the \c ADD_CONTAINER_ITERATOR macro:
+\code
+ADD_CONTAINER_ITERATOR( QuadratureSet )
+\endcode
+
+\section License
+
+Copyright (c) 2010, Seth R. Johnson
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the this project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This material is based upon work supported under a National Science
+ Foundation Graduate Research Fellowship. Any opinions, findings, conclusions
+ or recommendations expressed in this publication are those of the author
+ and do not necessarily reflect the views of the National Science
+ Foundation.
+*/
+#ifndef tools_SWIG_generators_i
+#define tools_SWIG_generators_i
+/*----------------------------------------------------------------------------*/
+
+// Add a Python class to provide iterator objects
+%insert("python") %{
+class GenericIterator:
+ def __init__(self, begin_iter_method, deref_method, incr_method):
+ self.it = begin_iter_method()
+ self.incr = incr_method
+ self.deref = deref_method
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ obj = self.deref( self.it )
+ if obj is not None:
+ self.incr( self.it )
+ return obj
+ else:
+ raise StopIteration
+%}
+
+//============== GENERIC GENERATOR/ITERATOR WRAPPER SUPPORT ============
+//! Thin wrapper for incrementing a certain type of iterator
+// only need to define once per iterator type, and we can use the same name
+// thanks to overloading (even though this may decrease efficiency)
+%define SETUP_GENERATOR( ITERATOR... )
+%inline %{
+void _iter_incr( ITERATOR* iter )
+{
+ ++(*iter);
+}
+%}
+%enddef
+
+/*----------------------------------------------------------------------------*/
+// Internal method for adding common parts of the generator
+%define PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
+ %extend CLASS {
+%insert("python") %{
+ def PYMETHOD(self):
+ "Returns an iterator for PYMETHOD."
+ return GenericIterator(
+ self._begin_ ## PYMETHOD,
+ self._deref_ ## PYMETHOD,
+ _iter_incr
+ )
+%}
+// get the first element in the vector
+ITERATOR* _begin_ ## PYMETHOD()
+{
+ return new ITERATOR( ($self)->CBEGIN() );
+}
+ }
+%enddef
+/*----------------------------------------------------------------------------*/
+// If the dereferenced iterator is an object
+%define ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND )
+
+// add the python and begin method
+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
+
+ %extend CLASS {
+//! Dereference the iterator; return NULL if at the end
+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter )
+{
+ // if at the end, return NULL
+ if (*iter == ($self)->CEND() ) {
+ return NULL;
+ }
+ // otherwise, return the POINTER to the dereferenced iterator
+ return &(**iter);
+}
+ }
+%enddef
+/*----------------------------------------------------------------------------*/
+// If the dereferenced iterator is a pointer
+%define ADD_GENERATOR_P( CLASS, PYMETHOD, ITERATOR, RVALUE, CBEGIN, CEND )
+
+// add the python and begin method
+PYTRT_BASE_ADD_GENERATOR( CLASS, PYMETHOD, ITERATOR, CBEGIN )
+
+ %extend CLASS {
+//! Dereference the iterator; return NULL if at the end
+const RVALUE* _deref_ ## PYMETHOD ## ( const ITERATOR* iter )
+{
+ // if at the end, return NULL
+ if (*iter == ($self)->CEND() ) {
+ return NULL;
+ }
+ // otherwise, return the dereferenced iterator (a pointer)
+ return **iter;
+}
+ }
+%enddef
+/*----------------------------------------------------------------------------*/
+//! For a regular container with "begin" and "end" and "size"
+%define ADD_CONTAINER_ITERATOR( CLASS )
+ SETUP_GENERATOR( CLASS::const_iterator );
+ ADD_GENERATOR( CLASS, __iter__,
+ CLASS ## ::const_iterator, CLASS ## ::value_type,
+ begin, end)
+ %extend CLASS {
+ %insert("python") %{
+ def __len__(self):
+ return self.size()
+ %}
+ }
+%enddef
+
+/*============================================================================*/
+#endif
+
diff --git a/hepmc/hepmcwrap.i b/hepmc/hepmcwrap.i
--- a/hepmc/hepmcwrap.i
+++ b/hepmc/hepmcwrap.i
@@ -1,5 +1,7 @@
%module hepmcwrap
+%include generators.i
+
%{
#include "HepMC/GenEvent.h"
#include "HepMC/GenVertex.h"
@@ -251,3 +253,9 @@
return ss.str();
}
}
+
+SETUP_GENERATOR( std::vector< HepMC::GenParticle* >::const_iterator )
+ADD_GENERATOR_P( HepMC::GenVertex, incoming,
+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_in_const_begin, particles_in_const_end)
+ADD_GENERATOR_P( HepMC::GenVertex, outgoing,
+std::vector< HepMC::GenParticle* >::const_iterator, HepMC::GenParticle, particles_out_const_begin, particles_out_const_end)

View File

@ -0,0 +1,20 @@
diff --git a/hepmc/hepmcwrap.i b/hepmc/hepmcwrap.i
index cf35c1b..b94fbe2 100644
--- a/hepmc/hepmcwrap.i
+++ b/hepmc/hepmcwrap.i
@@ -1,6 +1,7 @@
%module hepmcwrap
%{
+ #include "HepMC/Flow.h"
#include "HepMC/GenEvent.h"
#include "HepMC/GenVertex.h"
#include "HepMC/GenParticle.h"
@@ -93,6 +94,7 @@ namespace HepMC {
// headers before importing headers that use those classes.
// Result is that headers should probably be %included in an order
// which sees "contents before containers"
+%include "HepMC/Flow.h"
%include "HepMC/HepMCDefs.h"
%include "HepMC/SimpleVector.h"
// #ifdef HEPMC_HAS_ITERATOR_RANGES

View File

@ -5084,6 +5084,41 @@ in {
};
};
pyhepmc = buildPythonPackage rec {
name = "pyhepmc-${version}";
version = "0.5.0";
disabled = isPy3k;
src = pkgs.fetchurl {
url = "mirror://pypi/p/pyhepmc/${name}.tar.gz";
sha256 = "1rbi8gqgclfvaibv9kzhfis11gw101x8amc93qf9y08ny4jfyr1d";
};
patches = [
# merge PR https://bitbucket.org/andybuckley/pyhepmc/pull-requests/1/add-incoming-outgoing-generators-for/diff
../development/python-modules/pyhepmc_export_edges.patch
# add bindings to Flow class
../development/python-modules/pyhepmc_export_flow.patch
];
# regenerate python wrapper
preConfigure = ''
rm hepmc/hepmcwrap.py
swig -c++ -I${pkgs.hepmc}/include -python hepmc/hepmcwrap.i
'';
buildInputs = with pkgs; [ swig hepmc ];
HEPMCPATH = pkgs.hepmc;
meta = {
description = "A simple wrapper on the main classes of the HepMC event simulation representation, making it possible to create, read and manipulate HepMC events from Python code";
license = licenses.gpl2;
maintainers = with maintainers; [ veprbl ];
platforms = platforms.all;
};
};
pytest = self.pytest_30;
pytest_27 = callPackage ../development/python-modules/pytest/2_7.nix {};