Wednesday, July 23, 2014

Project: Detecting the 1420.4MHz hydrogen line -- status report

A while ago, I decided it would be a fun thing to try to detect the 21cm hydrogen line. The 21cm line is a hyperfine structure line of hydrogen; the latter is abundant in interstellar matter in our galaxy (and in other galaxies too). That makes this transition's radiation an interesting object to study, especially because you can determine the velocity of the regions emitting the raditation quite precisely by looking at the doppler shift of the radiation. That makes it possible to construct for example rotation profiles of galaxies. You can do that even if your spatial resolution is low (which is important, since spatial resolution is limited by the size of your antenna: as a rule of thumb, the area you see as one big smeared "pixel" is about the inverse of the size of your antenna expressed in wavelengths taken as radians -- so if your antenna is 1.05m big, which is 5 wavelengths at 21cm, that gives you a spatial resolution of about 1/5rad which is about 11 degrees. That's about 22 sun diameters, which is really bad if you wanted to make an image of the sky).

An antenna

First thing you need is an antenna. For this purpose, I built a 14-element Yagi antenna, as seen below.
14-element 1.4GHz Yagi antenna
Closeup of the amplifier next to the resonator of the antenna. The circuitry is hidden below the copper shielding.
It has quite a lot of tape on it -- I underestimated the size and need for mechanical stability a bit. For the next try, I will definitely use a more sturdy piece of wood as the base. Anyways, first measurements indicate that it should work well enough; not great, but good enough for a first test.
S11 of the yagi antenna shown above. x is frequency, y is log reflected power (lower is better).

A Preamplifier

The second thing in the signal path is a preamplifier, which is usually placed directly at the antenna and has the purpose of amplifying the received signal before any degradation can happen (e.g. through cables, which weaken the signal and add noise). The noise figure of the preamplifier (which is often called LNA, for low-noise amplifier) is important; it tells how much additional noise will be present in the detected signal. The noise figure of all subsequent amplifiers is usually not relevant: they amplify the noise added by the LNA, which is far worse than their own added noise. Thus, it makes sense to carefully design the very first amplifier, while the rest of them can be as cheap and simple as possible.
It is very difficult to design a good LNA though; so for some first tests, I use a generic wideband amplifier IC as my preamplifier, which has a not-very-good noise figure of 2dB. I hope it will work as a proof-of-concept; I plan to add a proper LNA later then.

More amplifiers

The next thing you want to do is to somehow amplify the received signal so much that its quality is limited by thermal noise: as soon as you reach that point, further amplification buys you nothing, you need to improve the antenna or cool your LNA. How much amplification that is exactly will depend on the circumstances, but since my measurement device can detect power levels down to roughly -120 dBm/Hz without problems and thermal noise from the antenna will probably be somewhere around -180 dBm/Hz, I will need somewhere around +60dB amplification at least -- better a bit more. That's about a factor one million more power.

Wide-band gain blocks are not a solution for every problem :(

My first attempt to achieve this was to use several more wideband amplifier blocks -- since they're cheap (~3€) and incredibly easy to use (connect signal in, signal out, add 5V power, done). That wasn't a very good idea for two reasons though:
First, besides the noise figure, another not-so-obvious disadvantage of a wideband amplifier is that it is, well, wideband: it will amplify everything, especially for example the very bright GSM (mobile phone stuff) band around 937 MHz. That is bad, because such a strong signal can cause intermodulation products which affect the quality of the signal you actually want to detect, or even cause the amplifiers to go into saturation.
Second, it is very easy to turn broadband amplifiers into oscillators. You have to strictly separate them from each other and avoid any kind of feedback, or they will start spitting out large power levels at seemingly random frequencies.
Both problems seem easy to solve by building a bandpass filter -- but I found it quite hard to build a good bandpass filter for 1.42GHz. It is a frequency where lumped-element filters (those made out of capacitors and inductors) are not really viable any more since you need capacitors with incredibly small values, while distributed-element (microstrip, see this blog post) filters are not that great either because a half- or quarter wavelength of 21cm is still pretty large.

A new experiment: Frequency Mixers

All those resaons taken together brought me away from using this simplest possible solution, so I decided to try what all the cool people do: use a frequency mixer to bring the signal down to a more manageable frequency after the preamplifier, then amplify and filter it at that low frequency. A frequency mixer is effectively a device which shifts the spectrum of a signal along the frequency axis: Mixing a 1GHz sine with a 995MHz sine will result in signals at the difference (and the sum) of those frequencies, so a 5MHz sine (and a 1995MHz sine, but that can easily be filtered away -- if you don't want it). Signal components which are shifted below 0Hz appear mirrored at the appropriate positive frequency (so, if a signal would be shifted to -3MHz, it will appear at 3MHz instead -- with a phase shift, but that is barely relevant).
Mixers are very versatile devices which are used basically everywhere where radio frequency signals are present -- for example in WLAN, in GSM, radio, or satellite television (in the latter, there's actually a mixer in the LNA thing which you put in front of your satellite dish which shifts the received ~10GHz signal to somewhere around 2GHz to reduce losses in the cable to your TV receiver).
Professional radio astronomy applications tend to use more than one mixer stage to lower the frequency gradually (that has various advantages mostly related to filtering), but I hope I can get away with just one stage for this project.

I thus built a test board based on the LT5560 mixer (~3€) which is designed to mix a 1420 MHz signal down to 20 MHz using a 1400 MHz local oscillator (LO, that's the name for the frequency you're mixing the signal you're interested in with). As the LO, I use a programmable frequency synthesizer I built a while ago which is based on the ADF4350 (~8€, but wow that thing is difficult to put on a working board -- took me three attempts with a new board design each).
ADF4350-based frequency synthesizer (left) controlled by a raspberry pi (right). This construction is used as the Local Oscillator (LO) for the mixer. A 1399.5 MHz signal is produced by this circuit on the coaxial cable on the left.

Balanced and Unbalanced signals

Apart from input matching, which is not very difficult to do since it is described in detail in the data sheet of the part, the one difficult thing which needs to be done when using a mixer of this type is that it requires balanced inputs, while the signal on your coax cable is usually unbalanced. The difference between those two is basically that the unbalanced signal has two voltage levels -- ground and the signal, while balanced has three, plus the signal, minus the signal, and ground. A device which converts one of those into the other is called a balun (for balanced-unbalanced). They always work both ways (balanced - unbalanced or unbalanced - balanced). A balun is usually made in one of two ways:
  • transformer type: the unbalanced signal is passed into a transformer and by clever choice of taps on the load side you can get a balanced signal
  • delay line type: transmission lines of certain fractions of the wavelength of the expected signals (e.g. 1/4 and 3/4) are connected to the balanaced signal, and tap different phases of the wave form because of their different length, which allows to extract a balanced signal
The former only works for low-ish frequencies (I don't know exactly how high you can go while they're still usable, but it will be somewhere in the few-hundred-MHz area, at least for handmade ones), the second one works for high frequencies as well but is very narrow-band (it only works for one specific kind of signal). In my test board, both are used: a delay-line type balun is used to convert the unbalanced input from the LNA into a balanced signal, and a transformer-type balun is used to convert the balanced mixer output into an unbalanced signal for the next amplifier stage.
I will not go into details on how to build those baluns here, but good documents describing how to do it include this, this (german), this and this (ready-made components are available and are not even very expensive, but I did not find any Europe-based distributor who actually sells them. And I don't want to pay $20 shipping fees and wait a week each time I need a part).
I checked the performance of the self-made baluns with a spectrum analyzer and directional coupler, and they seem to work well after a few experiments -- although I am not entirely happy with the performance of the transformer-type one: a return loss of -13dB means about 1/20 of the signal power will get reflected back into the mixer, which is more than I would like. I think one reason for this is that the windings of the wire are a bit chaotic which makes the coupling between the windings a bit non-deterministic. Still -- all good enough for the prototype ;)
The S11 curve of the delay-line one is much sharper than the one shown here, and it also has a better return loss at the design frequency.
S11 (return loss) of the transformer-type balun; x axis is frequency, y axis is log power
S11 of the delay line type balun. The resonance frequency around 1.4 GHz is easy to spot. The ripple at lower frequencies is probably at least partly an artifact of the measurement method. x axis is frequency, y axis is log power

But most important, it actually works:
Balanced signal created from an unbalanced input with the transformer balun. The yellow and teal curve show the plus and minus components of the balanced signal, the violet one is their difference, which resembles the original unbalanced signal. Input level is 0dBm.
A balun can also have an impedance transformation ratio, which in this case plays an important role in impedance matching. The transformer balun I built is a 16:1 balun, which takes a 800Ω unbalanced signal and turns it into a 50Ω balanced one -- very convenient for this mixer circuit here, since 800Ω is reasonably close to the mixer's output impedance (as detailed in the data sheet) at that frequency.

Results

LT5560 active mixer test board. Yes, it looks quite horrible because lots of repairs were needed after the initial fabrication ;) Next one will look nicer.

And after fixing several grave issues with the LT5560 test board (including components we forgot to solder onto the board, an accidental short-circuit of the power line which involved overlooking that the baluns both pass-through DC current, the lack of enough ground vias across the board, missing DC paths for the input pins, and an oscillating circuit involving the power supply (which was fixed by adding some 10Ω resistors in series with the RF chokes used) and a few more) it actually works! Look:
Output of the mixer circuit for 1.3995GHz LO frequency and 1.42 GHz input frequency. Upper panel is time domain (time -- voltage), lower panel is frequency domain (frequency -- power). A strong tone is present at the difference of the two frequencies (20.5 MHz, where the cursor is).
Mixer output for 1.3995GHz LO and 1.405 GHz input. If the input frequency is lowered to and then below the LO frequency, the frequency peak moves to the left until it hits zero frequency and then starts moving right again.
There's some fairly strong "noise" on the output which seems to be somewhere around 400 MHz. I'm not sure where that comes from (higher-order intermodulation product?) but it will be easy to remove through a low-pass filter.

Next steps

Now, most of the difficult components for my 1.42GHz receiver should hopefully be in place. I plan to build a 20 MHz amplifier and lowpass filter shortly; I hope to be able to present a few more concrete results here shortly!

Monday, March 17, 2014

kdevelop-python for Python 3: first stable version (1.6.0) released!

Yesterday, Python 3.4 was finally released, so I'm now happy to announce the first stable release of kdevelop-python which supports Python 3! See below for the tarballs.
As in the Python 2 series, PyQt continues to be one of the best supported frameworks.
Obsolete,  please use 1.6.1-py3 (see below) -- 1.6.0 didn't build on some systems kdev-python version 1.6.0-py3
http://download.kde.org/stable/kdevelop/kdev-python/1.6.0/src/kdev-python-v1.6.0-py3.tar.xz.mirrorlist
SHA256:974178fa00a34c5e2a4d9f6408c7fcbf92e7933182dd59216a11c1452238ceb7

kdev-python version 1.6.1-py3
http://download.kde.org/stable/kdevelop/kdev-python/1.6.1/src/kdev-python-v1.6.1-py3.tar.xz.mirrorlist
SHA256: 26b1fa25e8f24f1e0b801ece02b283a750e77543e6df1e571dd52b36778859a5


The kdev-python 1.6-py3 series is compatible with KDevelop 4.6 (kdevplatform 1.6) and is suitable for working with Python 3.x source code.
If you're only interested in using (as opposed to packaging or developing) kdev-python, you should consider installing kdev-python from your distribution's package manager instead of downloading the source code. 
The python 3 and python 2 versions cannot be installed at the same time currently!
There's not that much more to say than what was already said in the beta announcement, so I will just post some screenshots of what continues to work in the Python 3 version:
Code completion is powerful as ever and tries very hard to only make suggestions which are useful in the current context.
Code tooltips are still there, too.
As always, please report any bugs you might find to the bug tracker. Happy hacking!

Tuesday, March 4, 2014

kdevelop-python for python 3: beta release

Good news: Python 3.4 is about to be released, and with it kdevelop-python's first version to support Python 3. Until that happens in a few days, here's a beta:
kdev-python version 1.5.80-py3
http://download.kde.org/unstable/kdevelop/kdev-python/1.5.80/src/kdev-python-1.5.80-py3.tar.xz.mirrorlist
SHA256:99ca1ce97e2a7e553051be7505c17a921ab1aaf318999826ea285f771bcc538a

The kdev-python 1.6-py3 series is compatible with KDevelop 4.6 (kdevplatform 1.6) and is suitable for working with Python 3.x source code.
If you're only interested in using (as opposed to packaging or developing) kdev-python, you should consider installing kdev-python from your distribution's package manager instead of downloading the source code.
There are a few things which need to be announced about this, so read on!

Embedded Python fork

First and foremost, this abomination is finally gone in the -py3 series. Python 3.4 merged a patch which is required by kdev-python, and now we can use the system's python installation. This will especially make kdev-python comply with all distribution's requirements for packaging software, which means it will hopefully soon be available in all major distribution's package repositories.
This also means that kdev-python now depends on Python =3.4.

Python 2 compatibility

The py3 series is not compatible with Python 2, and currently you can not install kdev-python and kdev-python3 side-by-side. I will try to address this restriction in the future and I will also publish a script to install the two versions into separate environments, but for now that's what is like. Especially, for packagers, this means that kdev-python must conflict with kdev-python3. The problem cannot be solved by renaming all the files, it also requires new UI and glue code to be written to select the correct language version, which I only have done partially as of today.

Branch names in kdev-python.git

I also used this opportunity to reorganize the branches in kdev-python.git a bit:
  • python3 is now python3-legacy (do not use)
  • python3-nofork is now python3; this branch is the most recent (unstable) version of the python3 version of the plugin, and compiles against kdevplatform master
  • there's a 1.6-py3 branch which is like 1.6 but for python 3.
If you had any of the renamed branches checked out, you might need to do git reset --hard origin/branchname. In the near future, master will also be renamed to python2 and python3 will be renamed to master (but not yet).

Feature comparison of kdev-python3 and kdev-python2

Generally, the Python 3 version has all the features from Python 2 plus a few more and some bug fixes. Not all new Python 3 features are understood yet (the syntax is supported, but the semantics isn't, e.g. nonlocal does nothing), though. What is there however is support for function annotations:
If the expressions in a function annotation represent a type (i.e. not an instance or something different) they are used to adjust the function's return and argument types.
I really hope this feature gets used for type hints, so this is a first step to encourage you to use it for that. ;)
Not all is awesome just yet, though: Although I'm not aware of any major issues, there will be regressions (things which were working in Python 2 but are now broken). There are always regressions, even with the ~90% test coverage kdev-python has. That's the purpose of this beta: go forth and test, and report all the bugs to the tracker so they can be slain!

Friday, February 7, 2014

kate: intelligent code completion for all languages!

... well, maybe that's a bit of an exaggeration, but it's certainly much more intelligent than before. Look:

Code completion in CSS
... bash
... Lua
... PHP
even Gnuplot!
Note how this one has a different set of possible items for the same query, respecting the context.
Even Mathematica ;) This image shows a problem which still needs to be fixed: in case-insensitive languages, all completion suggestions are lowercased (which is not technically wrong of course, but a  bit ugly). It's easy to fix but simply not done yet.
There's unexpected profit from this in quite some areas, even KDevelop: for example, through this we now get code completion for all keywords in doxygen comments:
Completion for doxygen keywords inside a doxygen comment
Of course, those only appear inside actual doxygen, and not C++. When the cursor is in C++ code, it shows the C++ keywords instead (but they will not be very visible in KDevelop, since they're sorted below KDevelop's suggestions, which are better).

How does this work?

Short answer: magic! Correct answer: it uses the highlighting files. For highlighting, kate has a list of possible keywords for languages listed in highlighting files (/usr/share/apps/katepart/snytax/$language,xml). Those keywords are even context-sensitive: you will notice that e.g. the PHP highlighter does not highlight PHP function names inside comments or strings. So, the highlighting engine needs to know which keywords are valid at which position. Those are precisely the keywords which are suggested in the list.

What now?

Now that we have this feature, I think we can make more out of it in quite some cases. Especially, I want to invite you to have a look at your favourite language, and make sure all keywords / builtin functions / etc. are actually listed. Because of this feature, it might make sense to list keywords for languages where they are not terribly helpful for highlighting; a prominent example would be HTML, where currently the highlighter is totally generic and does not actually look at e.g. the tag names (thus, there's no completion). If you'd fix that by actually listing all valid HTML tag names, you'd (1) get better highlighting, e.g. you can mark undefined elements (think typos) as errors and (2) completion for free with that.

Another thing which can be improved is the context sensitivity. Some languages already do this rather well, but many languages will higlight keywords also in places where it'd be easy to detect that the keyword does not make sense there. That doesn't matter that much for highlighting only, because generally users write code which makes sense, but still -- if you can detect it, both consumers of the highlighting data (the actual highlighting, and the completion engine) gain something from it. So, extra motivation for making things more exact! ;)

I'm sure we can do more cool stuff with this. If you can come up with a good idea -- tell me, I'm happy to talk about it.

Sunday, January 26, 2014

KDevelop / Kate sprint in Barcelona in January 2014

Last week I have been in Barcelona at the KDevelop / Kate sprint with all the other nice people working on those projects. As always, it was very cool to meet everyone again and spend a week together improving software. A big thanks to the organizers and sponsors, too!

Since most of the time I work on a fairly encapuslated subsystem (Python support for KDevelop) and only a smaller part of my contributions goes towards the KDevelop / Kate core repositories, I don't  have any world-changing news to announce -- unlike for kate and KDevelop, no Qt5 / KF5 porting is happening yet in Python support. It doesn't make much sense to start porting until all the interfaces have stabilized.

Still, quite some interesting things have piled up in the last few months, and especially during the sprint.
In the following, I want to give a quick summary of those.

Tuesday, October 29, 2013

kdev-python update: version 1.5.2 released

I'm happy to announce the availability of a second stabilization update for the 1.5 series of kdev-python, the Python language support plugin for the KDevelop development environment. See the 1.5 announcement for more information.
kdev-python version 1.5.2
http://download.kde.org/stable/kdevelop/kdev-python/1.5.2/src/kdev-python-v1.5.2.tar.xz.mirrorlist
SHA256:84ae7015623a3848b1c1ce8e8f958c32778e9ba0afafa3ea3b3dd70687e1fe40

The kdev-python 1.5 series is compatible with KDevelop 4.5 (kdevplatform 1.5) and is suitable for working with Python 2.x source code.
If you're only interested in using (as opposed to packaging or developing) kdev-python, you should consider installing kdev-python from your distribution's package manager instead of downloading the source code.
kdev-python running in KDevelop master
Changes in this release (relative to 1.5.1):
  • Fix a bug which led to the PEP8 checker running on non-python files in some cases
  • Properly support unicode docstrings (thanks to Alexandr Zamaraev)
  • Fix a crash in code completion which happened in some rare cases
  • Fix a crash which could happen when a list comprehension was used as the default value for a function parameter
This is a small update containing only the above 4 bug fixes; all users are urged to switch to the new version as soon as it becomes available in their distribution.

There will be a larger update containing various cool new features in a few weeks, so stay tuned!

Monday, October 28, 2013

kte-collaborative 0.2: First stable release of the collaborative text editing project

I'm pleased to announce the first stable release of kte-collaborative, which provides collaborative text editing in kate through kde-telepathy, and an update to the libqinfinity library.
libqinfinity version 0.5.2:
http://download.kde.org/stable/libqinfinity/0.5.2/src/libqinfinity-v0.5.2.tar.xz.mirrorlist
SHA256: 739f99afb7fd464e4b541e2980e07911c8f30924f9871f14294dc3148137825a

kte-collaborative version 0.2.0 (aka 0.2):
http://download.kde.org/stable/kte-collaborative/0.2.0/src/kte-collaborative-v0.2.0.tar.xz.mirrorlist 
SHA256: 06c8cfb16b93a8fe3c5e2267ba3f71110526966267f73fed20a902c3f7982a55

kte-collaborative 0.2 depends on kde-telepathy 0.7 beta or later, and works with libinfinity 0.5.x.
kte-collaborative 0.2, with dolphin listing some files from gobby.0x539.de and editing a file in kate.
There have not been many noteworthy user-visible changes since the last beta release, so please to refer to the 0.2 beta announcement for more information. As always, please report any bugs you find to bugs.kde.org!