Thursday, 10 March 2016

Solar Oscillations Demo

One of my favourite programs from Sky and Telescope magazine's Astronomical Computing column was one which produced a visualisation of oscillations on the surface of the Sun. Although these oscillations were discovered in 1960 they gained more attention during the 1990s due to the very successful MDI instrument on board the SOHO spacecraft.

The program uses Legendre polynomials to illustrate the red- and blueshift of light due to pressure waves at the surface. The user specifies the degree L (typically up to 150) and order M (not exceeding L) of the oscillation mode. In reality the Sun contains many such wave modes superimposed.

Below is a mostly faithful port to C/C++ using bitmap output to ensure cross-platform compatibility. I'm using GCC version 5.3 and the code should compile on almost any PC or ARM-based computer (for example Raspberry Pi). The bitmap writing function assumes a little-endian CPU.

/*
 Solar Surface Oscillations
 SOLAROSC.BAS by John Kennewell
 */
#include <cmath>
#include <iostream>
#include <cstdio>

void writeBitmapFile(int x, int y, unsigned int *data);

using namespace std;

class LegendrePoly
{
public:
 static const double HALF_PI = 3.1415926535897936 / 2.0;
 static const int SAMPLES = 400;

 LegendrePoly(int _l, int _m)
  : l(_l), m(_m)
 {}

 ~LegendrePoly() {}

 double evaluate(const double cost)
 {
  int idx = (cost + 1.0) * SAMPLES / 2;
  return p[idx];
 }
 // Generate Legendre function
 void generate()
 {
  double max_val = 0;
  for(int xi = 0; xi < SAMPLES; ++xi)
  {
   double x = ((double)xi - SAMPLES/2) / (SAMPLES/2);
   double d = sqrt(1 - x*x);
   double p1 = exp(l * log(d)), p2 = 0; // p1 = (1 - x^2)^(l/2)

   for(int li = 1; li <= (2*l - 1); li += 2)
    p1 *= li;

   if ((m >= l) || p1 == 0) continue;
   double pm;
   for (int mi = l-1; mi>=m; --mi)
   {
    pm = 2 * (mi+1) * x * p1 / d - p2;
    pm /= ((l-mi) * (l+mi + 1));
    p2 = p1; p1 = pm;
   }
   p[xi] = p1;
   if(abs(p1) > max_val)
    max_val = abs(p1);
  }
  // normalise
  for(int xi = 0; xi < SAMPLES; ++xi)
   p[xi] /= max_val;
 }

private:
 const int l, m; // Degree and order of Legendre function
 double p[SAMPLES]; // polynomial coeffs
};


unsigned int colourLookup(double s)
{
 // rc = rd * INT((15 - i) * 4.5)
 // bc = bl * INT((i - 1) * 4.5)
 // gc = gn * INT((7 - ABS(8 - i)) * 4.5)
 unsigned int red =   (unsigned int)((1-s) * 255);
 unsigned int blue =  (unsigned int)(s * 255);
 unsigned int green =  (unsigned int)((0.6 - abs(s-0.5)) * 255);
 return (blue | (green << 8) | (red << 16));
}

int main(int argc, char **argv)
{
 int L, M;
 unsigned int data[400*400];

 cout << "Enter degree L and order M: ";
 cin >> L >> M;
 cout << "Solar Global Oscillations, Mode L =" << L << ", M =" << M << endl;

 LegendrePoly poly(L,M);
 poly.generate();

 // Plot solar hemisphere
 double s;
 for(int y=0; y<400; ++y)
 {
  double cost = (y-200.0) / 200;
  double sint = sqrt(1 - cost*cost);
  double pm = poly.evaluate(cost);
  for(int x=0; x<400; ++x)
  {
   double sinf = (x-200.0) / 200 / sint;
   if ((sinf > -1) || (sinf < 1))
   {
    double cosf = sqrt(1 - sinf*sinf);
    double phi = LegendrePoly::HALF_PI * sinf / abs(sinf);
    if (cosf != 0)
     phi = atan2(sinf, cosf);
    s = pm * cos(M * phi) * sint * cosf;
    data[400*y+x] = colourLookup(s/2+0.5);
   }
  }
 }
 writeBitmapFile(400, 400, data);
}


void writeBitmapFile(int x, int y, unsigned int *data)
{
 FILE *fp;
 fp = fopen("solar_osc.bmp", "w");

 /* BMP header */
 fwrite("BM", 2, 1, fp);
 int filesize = x*y*4 + 14 + 40; // 4 bytes per pixel
 fwrite(&filesize, sizeof(filesize), 1, fp);
 // reserved 
 fwrite("SOLO", 4, 1, fp);
 // offset to image data
 int offset = 40;
 fwrite(&offset, sizeof(offset), 1, fp);

 /* DIB header: BITMAPINFOHEADER */
 int hdrsize = 40; // header size in Bytes
 fwrite(&hdrsize, sizeof(hdrsize), 1, fp);
 fwrite(&x, 4, 1, fp);
 fwrite(&y, 4, 1, fp);

 short num_planes = 1, color_depth = 32;
 fwrite(&num_planes, 2, 1, fp);
 fwrite(&color_depth, 2, 1, fp);

 int comp_format = 0;
 fwrite(&comp_format, 4, 1, fp);
 int size = x*y*4; // 4 bytes per pixel
 fwrite(&size, sizeof(size), 1, fp);

 fwrite(&x, 4, 1, fp);
 fwrite(&y, 4, 1, fp);
 char padding[] = {0,0,0,0};
 fwrite(padding, 4, 2, fp);

 // image data
 fwrite(data, size, 1, fp);
 fclose(fp);
}

Links

Sunday, 31 August 2014

Using libINDI with an Atik camera on Linux

In June I obtained an Atik 314L+ cooled CCD camera which I plan to use primarily for spectroscopy (see Shelyak Instruments). As a Linux user I needed a Linux USB driver and also an easy-to-use image capture program.

Three tools need to be set up to use the camera:

  1. Atik linux driver
  2. Wrapper interface known as libINDI which is widely adopted for astronomical CCD cameras, filter wheels and mounts. It is based on a client-server model using XML to pass commands between the client (for example KStars) and a server which interacts with the USB device such as a camera.
  3. KStars, which contains a module named Ekos for image capture. Version 2.2 or later is required.

1. Atik linux driver

Install the Debian or RPM atikccd package from CloudMakers.eu. Both 32-bit (X86) and 64-bit (X86_64) are supported as well as ARM11 architecture used in the Raspberry Pi.

Check the installation was successful by attaching the Atik camera and running:

atik_ccd_test

I've tried Ubuntu 12.04 and 14.04 without any problem.

2. libINDI

On Ubuntu the package libindi0 and libindi-data can be installed from the repository. The latest version (0.9.8 at time of writing) is available by adding Jason Mutlaq's repository.

sudo add-apt-repository ppa:mutlaqja/ppa

You will also need libindi-dev if you build KStars from source (see below), or if you plan to write your own libINDI client. (Fun project for a rainy weekend?)

3. KStars

You need at least version 2.2 for the Ekos image capture module, which I find easy to use and well-integrated with the rest of KStars. As it's a KDE program you need several support libraries to run on Gnome-based Ubuntu.

Ubuntu 14.04

Simply install KStars from the Ubuntu Software Centre (or using apt-get on the command line).

Ubuntu 12.04

I have a Dell Mini 10 netbook using the Intel Poulsbo chipset which may not be fully supported in Ubuntu 14.04. As I have OpenGL acceleration working more-or-less well I decided to stick with Ubuntu 12.04 which ships with KStars 2.0. Hence I needed to build the latest KStars (tag v4.14.0 at the time of writing; the tag corresponds to the targeted KDE version) to get the Ekos module.

There are helpful instructions at Building KStars. In addition to the package dependencies listed there, you may need to install.

apt-get install libindi-dev kdelibs5-experimental-dev

Finally you should be able to select Atik CCD from the menu and capture a test exposure which can be saved in FITS format. The image below shows a spectrum of Spica taken on 14th June. Spica was close to the window frame hence the stray light!

Links

Thursday, 31 January 2013

Setting up a Django-Nginx web server on Raspberry Pi

Today I installed the Django web framework on my Raspberry Pi, using Nginx as the web server and fastcgi to delegate page requests to Django. Here is a summary of the steps involved, for future reference. I hope it's effective so please comment if anything is unclear.

1. Install Django and Nginx

I used Paul Hallett's one-click installer. When it finishes it reports the Django version (such as 1.4.1) if successful. Note that his script installs a local version of Python so bear in mind some packages may need to be symlinked to work.

2. Configure Nginx

There's a useful and informative article on using Nginx for personal websites on Ars Technica. Ignore the part to install the development version because there isn't a pre-built package for the ARM11 CPU used in the Raspberry Pi. Once installed (I'm using nginx version 1.2.1 from the Raspbian repository), you need to edit the file: /etc/nginx/nginx.conf

worker_processes 1;
The Raspberry Pi has only a single CPU core so there's no need for more than one worker process. This file can also be tweaked for compressing large files, and to improve security (not covered here).

Create a new website corresponding to a URL such as www.mysite.org by copying the default file. Name it according to your URL.

cd /etc/nginx/sites-available/
cp default www
ln -s /etc/nginx/sites-available/www /etc/nginx/sites-enabled/www
rm /etc/nginx/sites-enabled/default
The last 2 commands enable your new site and disable the default one. Edit the new file as follows:
server {
 listen   80;
 #listen   [::]:80 default_server ipv6only=on;

 root /var/html/www;
 index index.html index.htm;
 access_log /var/log/nginx/www.access.log;
 error_log /var/log/nginx/www.error.log;

 # Make site accessible from http://localhost/
 server_name localhost;

 location / {
  # First attempt to serve request as file, then
  # as directory, then fall back to displaying a 404.
  # try_files $uri $uri/ /index.html;
  # Uncomment to enable naxsi on this location
  # include /etc/nginx/naxsi.rules

  # Django
  # https://code.djangoproject.com/wiki/DjangoAndNginx
  include fastcgi_params;
  fastcgi_pass 127.0.0.1:8080;
 }
}

The root tag is where your website files would normally be installed. However, your Django site can be placed anywhere. The access_log and error_log tags are useful for logging information. The important tags are include fastcgi_params and fastcgi_pass 127.0.0.1:8080 which tells nginx to forward page requests to Django on port 8080. See the Django and Nginx Wiki for further info. Restart nginx to load your new settings.

sudo /etc/init.d/nginx reload

3. Set up Django and fastcgi

Install Flup and ensure it's in your Python path (check your local configuration). Version 0.5 or later should be ok, I have 1.0 from the Raspbian repo.

sudo aptitude install python-flup
sudo ln -s /usr/lib/python2.7/dist-packages/flup* \
  ~/lib/python2.7/site-packages/

4. Create a test website

Following the Django tutorial, create your test site as follows.

django-admin.py startproject mysite
cd mysite
python ./manage.py runfcgi host=127.0.0.1 port=8080
Your website is now running and if all goes well Nginx will forward requests to port 8080. Type in the IP address of your Raspberry Pi into a browser window on another machine, and you should see a welcome to Django message. That means it worked! :)

Links

Wednesday, 16 November 2011

Extrasolar planets -- 1 year later


Last October (2010) I wrote a post on extrasolar planets. At that time almost 500 planets beyond our Solar System had been discovered. In the past year, 200 new planets have been confirmed, so I decided it's time to update the chart!

There are a number of recent discoveries around 10 Earth masses (0.03 Jupiter masses) and an over abundance of planets at 0.05 AU (7 million kilometres) from their parent Sun, the well-known 'hot Jupiters'. There is another class of cooler giant planets around 1-5 AU. Several 'super Earths' discovered by micro-lensing can also be seen on the chart.

Will there be 1000 known planets when I update the chart in autumn 2012? Let's see!

Wednesday, 3 August 2011

Pluto's 4th moon

Recent Hubble images have revealed a new moon orbiting Pluto, the fourth so far discovered around the icy dwarf planet. P4 as the moon is currently known, is the smallest so far discovered at 15 to 30km across, and lies between Nix and Hydra, two small moons discovered in 2005.






MoonMean distance (km)Period (d)Year of discovery
Charon17,5406.3871978
Nix48,71024.8562005
S/2011 P1~59,00032.12011
Hydra64,75038.2062005



The moon was unexpectedly found during an observing campaign to find rings around Pluto, which remain undiscovered. The new moon was first seen in an image taken on the 28th June and will be further studied during NASA's New Horizons mission, scheduled to fly through the Pluto system in 2015.

Links


Tuesday, 10 May 2011

A foray into Spectroscopy

In January I acquired a `Star Analyser 100 spectroscope', a diffraction grating which screws into a 1.25-inch eyepiece just like a colour filter. Well, here are my first results captured with an Imaging Source DFK21 camera and processed with Valerie Desnoux's Visual Spec software which is excellent (and free!).

Betelgeuse spectrum

I used Sirius (spectral type A0V) to calibrate the image which has a resolution of 10.5 Angstroms per pixel. The final spectrum (green) is shown between 4000 and 7000 Angstroms (note my response curve has sadly missed the Halpha line at 6563 Angstroms) based on 17 seconds of raw video. The black curve shows a reference red supergiant spectrum of class M2.

Also shown for interest are the Balmer series of H lines (red) and Ti lines (blue).

Links


Friday, 18 February 2011

AstroFest 2011

For 2 days each year at the start of February, the UK astronomy magazine "Astronomy Now" organises a national festival celebrating recent news in astronomy and bringing amateurs together to hone their skills. This year I was lucky to visit the conference on both Friday and Saturday and there were some excellent talks on Phobos and Deimos (Emily Baldwin), epsilon Aurigae (Nathalie Thureau), Uranus & Neptune (Chris Arridge) and the Moon (Chuck Wood) amongst several others. Sadly I missed the principal galactic astronomy talk by Gerry Gilmore of Cambridge University because session 4 (Saturday afternoon) was already sold out.


I also enjoyed the trade stalls in particular those of the BAA and Ian King Imaging/Shelyak Instruments, the latter a French company specialising in spectroscopes for amateur astronomers. I would love to buy their LISA instrument but the Star Analyser is more realistic for my budget/telescope!



Ian Ridpath during the Friday afternoon session interval




Nathalie Thureau describes the CHARA infra-red interferometer




"It's not Rocket Science", a very amusing space-themed comedy show by Helen Keen (Radio 4 in March/April)




Links