def test(self): "codes for boost python binding" from mcstas2.wrappers.component2cppClass.component2cppClass import component2cppClass klass = component2cppClass( componentfile ) from mcstas2.utils.parsers import parseComponent compinfo = parseComponent( componentfile ) # create directory dir = "E_monitor" if not os.path.exists(dir): os.makedirs(dir) from mcstas2.wrappers.pymodule import generate sources = generate( compinfo, bpbindingname, projectpath ) self.assertEqual( sources[0], '%s/%s.py' %(componentname, componentname) ) return
def test(self): "codes for boost python binding" from mcstas2.wrappers.component2cppClass.component2cppClass import component2cppClass klass = component2cppClass(componentfile) from mcstas2.utils.parsers import parseComponent compinfo = parseComponent(componentfile) # create directory dir = "E_monitor" if not os.path.exists(dir): os.makedirs(dir) from mcstas2.wrappers.pymodule import generate sources = generate(compinfo, bpbindingname, projectpath) self.assertEqual(sources[0], '%s/%s.py' % (componentname, componentname)) return
def component2cppClass( comp_filename ): #parse the mcstas component and get infos we want from mcstas2.utils.parsers import parseComponent compInfo = parseComponent( comp_filename ) return componentInfo2cppClass( compInfo )
def createBindingObject( componentfilename, componentcategory, pythonpackage = None, path = None, componentname = None, bindingname = None, bindingtype = 'boostpython'): """Create the binding object of a McStas component in python componentfilename: component file path. Eg. /.../monitors/E_monitor.comp componentcategory: category of component. Eg. monitors pythonpackage: the python package where this component will be export to. Eg. mcstas.components.monitors path: temporary path where binding sources go componentname: name of the component. Eg. E_monitor bindingname: name of the binding. Eg. E_monitorboostpython bindingtype: type of binding. Eg. boostpython (currently only this is supported) """ debug.log( 'pythonpackage=%s' % pythonpackage ) if pythonpackage is None: pythonpackage = 'mcstas2.components.%s' % componentcategory pass if not path: import temporaryfiles path = temporaryfiles.temporarydir() debug.log('generateing wrapper in %s' % path) pass if not componentname: componentname = os.path.splitext( os.path.basename( componentfilename ) )[0] pass if not bindingname: bindingname = '%s%s' % (componentname, bindingtype) # read component info from mcstas2.utils.parsers import parseComponent compInfo = parseComponent( componentfilename ) # generate c++ sources for the component from component2cppClass.component2cppClass import componentInfo2cppClass klass = componentInfo2cppClass( compInfo ) from mcstas2.utils.mills.cxx.factory import createHHandCC hh, cc = createHHandCC( klass, path ) # generate bindings for the c++ class from binding import binding binding = binding( bindingtype ) bindingsources = binding.generate_binding_sources( bindingname, klass, path ) # genearte python code to wrap the binding into a factory method from pymodule import generate pysources = generate( compInfo, bindingname, path ) if bindingsources.get( 'python' ) is None: bindingsources['python'] = pysources else: bindingsources['python'] += pysources # build binding from mcstas2.release import mcvinedir as export_root export_include = os.path.join(export_root, 'include') danse_dir = os.environ.get('DANSE_DIR') or '' danse_ins_include = os.path.join(danse_dir, 'include') export_lib = os.path.join(export_root, 'lib') danse_ins_libs = [ os.path.join(danse_dir, 'lib64'), os.path.join(danse_dir, 'lib'), ] from binding_builder import binding as bindingdataobject bindingobj = bindingdataobject( python_package = pythonpackage, binding_module = bindingname, c_headers = [ hh ], c_sources = bindingsources['c'] + [cc], python_sources = bindingsources['python'], c_libs = ['mcstas2', 'mcstas2_share', 'mcni' ] + binding.libstolink, c_libdirs = [export_lib] + danse_ins_libs, c_includes = [export_include, danse_ins_include], c_defines = binding.define_macros, dependencies = [ bindingtype, 'caltech-config', 'mcstas2', 'mcni' ], ) return bindingobj, klass.name, componentcategory, componentname
def wrap(componentfilename, componentcategory, pythonpackage=None, path=None, componentname=None, bindingname=None, bindingtype='boostpython', buildername='mm', pythonexportroot=None): """wrap a McStas component in python componentfilename: component file path. Eg. /.../monitors/E_monitor.comp componentcategory: category of component. Eg. monitors pythonpackage: the python package where this component will be export to. Eg. mcstas.components.monitors path: temporary path where binding sources go componentname: name of the component. Eg. E_monitor bindingname: name of the binding. Eg. E_monitorboostpython bindingtype: type of binding. Eg. boostpython (currently only this is supported) buildername: binding builder. choices: mm and distutils pythonexportroot: directory where python modules are exported. Eg. $EXPORT_ROOT. None means pyton modules will be exported wherever the binding builder's default export path. """ debug.log('pythonpackage=%s' % pythonpackage) if pythonpackage is None: pythonpackage = 'mcstas2.components.%s' % componentcategory pass if not path: import temporaryfiles path = temporaryfiles.temporarydir() debug.log('generateing wrapper in %s' % path) pass if not componentname: componentname = os.path.splitext( os.path.basename(componentfilename))[0] pass if not bindingname: bindingname = '%s%s' % (componentname, bindingtype) # read component info from mcstas2.utils.parsers import parseComponent compInfo = parseComponent(componentfilename) # generate c++ sources for the component from component2cppClass.component2cppClass import componentInfo2cppClass klass = componentInfo2cppClass(compInfo) from mcstas2.utils.mills.cxx.factory import createHHandCC hh, cc = createHHandCC(klass, path) # generate bindings for the c++ class from binding import binding binding = binding(bindingtype) bindingsources = binding.generate_binding_sources(bindingname, klass, path) # genearte python code to wrap the binding into a factory method from pymodule import generate pysources = generate(compInfo, bindingname, path) if bindingsources.get('python') is None: bindingsources['python'] = pysources else: bindingsources['python'] += pysources # build binding from mcstas2.release import mcvinedir as export_root export_include = os.path.join(export_root, 'include') export_lib = os.path.join(export_root, 'lib') from binding_builder import binding as bindingdataobject bindingobj = bindingdataobject( python_package=pythonpackage, binding_module=bindingname, c_headers=[hh], c_sources=bindingsources['c'] + [cc], python_sources=bindingsources['python'], c_libs=['mcstas2', 'mcstas2_share', 'mcni'] + binding.libstolink, c_libdirs=[export_lib], c_includes=[export_include], c_defines=binding.define_macros, dependencies=[bindingtype, 'caltech-config', 'mcstas2', 'mcni'], ) from binding_builder import builder builder(buildername).build(bindingobj, pythonexportroot) # register the new factory from mcstas2.components import registercomponent m = __import__('%s.%s' % (pythonpackage, klass.name), {}, {}, ['']) registercomponent(componentcategory, componentname, m) return
def test(self): "parse E_monitor component" from mcstas2.utils.parsers import parseComponent component = parseComponent( 'E_monitor.comp' ) # print dir(component) attrs = [ 'name', 'full_description', 'simple_description', 'initialize', 'trace', 'finalize', ] for attr in attrs: assert hasattr(component, attr) self.assertEqual(component.name, 'E_monitor') self.assert_(component.copyright.startswith('Kristian Nielsen and Kim Lefmann')) self.assertEqual( component.simple_description, 'Energy-sensitive monitor.') self.assert_( component.full_description.strip().startswith( 'A square single monitor' ) ) ips = component.input_parameters ips0 = ips[0] self.assertEqual(ips0.name, 'name') self.assertEqual(ips0.type, 'char *') self.assertEqual(ips0.default, 'e_monitor') ips1 = ips[1] self.assertEqual(ips1.name, 'nchan') self.assertEqual(ips1.type, 'int') self.assertEqual(ips1.default, 20) ips2 = ips[2] self.assertEqual(ips2.name, 'filename') self.assertEqual(ips2.type, 'char *') self.assertEqual(ips2.default, 'e.dat') ips3 = ips[3] self.assertEqual(ips3.name, 'xmin') self.assertEqual(ips3.type, 'double') self.assertAlmostEqual(ips3.default, -0.2) self.assertEqual( component.state_parameters, ['x', 'y', 'z', 'vx', 'vy', 'vz', 't', 's1', 's2', 'p'] ) self.assertEqual( component.output_parameters, [] ) self.assertEqual( component.declare.strip(), 'double *E_N, *E_p, *E_p2;', ) self.assertEqual( component.initialize.strip(), '''int i; E_N = (double *)malloc(nchan*sizeof(double)); E_p = (double *)malloc(nchan*sizeof(double)); E_p2 = (double *)malloc(nchan*sizeof(double)); for (i=0; i<nchan; i++) { E_N[i] = 0; E_p[i] = 0; E_p2[i] = 0; }''') self.assertEqual( component.trace.strip(), '''int i; double E; PROP_Z0; if (x>xmin && x<xmax && y>ymin && y<ymax) { E = VS2E*(vx*vx + vy*vy + vz*vz); i = floor((E-Emin)*nchan/(Emax-Emin)); if(i >= 0 && i < nchan) { E_N[i]++; E_p[i] += p; E_p2[i] += p*p; SCATTER; } }''') self.assertLinesEqual( component.save.strip(), '''#ifdef DEBUG printf("E_monitor: save\\n"); #endif DETECTOR_OUT_1D( "Energy monitor", "Energy [meV]", "Intensity", "E", Emin, Emax, nchan, &E_N[0],&E_p[0],&E_p2[0], filename);''') self.assertLinesEqual( component.finalize.strip(), '''#ifdef DEBUG printf("free: E_N = %p, E_p = %p, E_p2 = %p\\n", E_N, E_p, E_p2); #endif free(E_N); free(E_p); free(E_p2);''') return