The Python C-API

Wed 03 April 2019 by Michael Olberg

Extending the Python Interpreter with C/C++

The Python interpreter can be extended via C (or C++) code to

  1. make existing python code execute faster by replacing critical sections into compiled code
  2. interface to existing/legacy C (or C++) libraries
  3. make C structures (C++ classes) first class objects within python

In my work I was guided by the following documentation (Python 3.0): extending and embedding the Python interpreter

In my demonstration I'll be using an interface I wrote to the CLASSIC data format (used by CLASS/GILDAS), please ask me for the source code if you are interested.

To start with I wrote some C++ classes which implement a reader class for the two types of CLASSIC files, V1 or V2. My C++ code allows to open a file, determine the file type and return a reader which will allow to retrieve the header, data vector or frequency vector for a given id, which ranges from 1 to the number returned by the getDirectory method. Example below is for the V2 reader class:

/**
 * A class to read a CLASSIC file of type 2.
 *
 */
class Type2Reader : public ClassReader {

 public:
    Type2Reader(const char *);
    ~Type2Reader();

    int getDirectory();
    SpectrumHeader getHead(int scan);
    std::vector<double> getFreq(int scan);
    std::vector<double> getData(int scan);

 private:
    void getFileDescriptor();
    void getEntry(int k);

    FileDescriptor2 fdesc;
    Type2Entry centry;
    ClassSection2 csect;
    long int ext[MAXEXT];
};

In my Python code I wanted to be able to use code like the following:

import sys
import pandas as pd
import numpy as np

import classic  # my python module!

print(classic.version())

if len(sys.argv) == 1:
    print("usage: %s <filename>" % (sys.argv[0]))
    sys.exit(1)

classfile = sys.argv[1]
foo = classic.Reader(classfile)

# get number of spectra in file
nscans = foo.getDirectory()
print("number of spectra = %d (%d)" % (nscans, foo.count))

headers = []
for i in range(nscans):
    headers.append(foo.getHead(i+1))

df = pd.DataFrame(headers)

iscan = 1
if len(sys.argv) > 2:
    iscan = int(sys.argv[2])

freq = foo.getFreq(iscan)
data = foo.getData(iscan)
nchan = len(freq)
for i in range(nchan):
    print("%10.5f %10.5f" % (freq[i], data[i]))

All code is available at this git repository.


Some features of numpy arrays

Wed 06 February 2019 by Franz Kirsten

Installation

  • assuming you have 'pip' installed run the following
pip install numpy
read more

pandas

Wed 12 December 2018 by Chiara Ceccobello

pandas: powerful Python data analysis toolkit

Useful links:

A tip: Whenever you are using pandas in your own code, try and stick to the following convention:

import pandas as pd

This will make it easier for other people to understand your …

read more

astropy - the python astronomy package

Wed 14 November 2018 by Franz Kirsten
  • get it from here
  • there are a number of great examples to get you started (the examples I showed in the seminar came from here)
  • and further tutorials
  • also check out the astropy-page on the WCS

What it can be used for (biased, certainly not complete list)

  • reading+writing standard …
read more

Coding in python in a Jupyter Notebook

Thu 22 March 2018 by Franz Kirsten
read more

Anaconda

Thu 15 March 2018 by Magnus Persson

The Anaconda distribution for Python

  • The slides are in this anaconda.pdf

  • Anaconda is a distribution for python which

    • comes with pre-built and pre-configured collection of packages
    • package manager (conda)
    • version management
    • ... and more
  • Freemium software from Continuum Analytics

  • Works basically the same on Win, Mac and Linux
  • Self-contained, install …
read more