<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Journey's End</title><link href="/" rel="alternate"/><link href="/feeds/all.atom.xml" rel="self"/><id>/</id><updated>2025-05-24T13:35:00+10:00</updated><entry><title>Thoughts on entropy, compression and predictors</title><link href="/thoughts-on-entropy-compression-and-predictors.html" rel="alternate"/><published>2025-05-24T13:35:00+10:00</published><updated>2025-05-24T13:35:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2025-05-24:/thoughts-on-entropy-compression-and-predictors.html</id><summary type="html">&lt;p&gt;I will prefix this post by saying that none of the ideas here are new and its all well covered ground by now. Like much of this blog, I am mostly writing to clarify ideas and to serve as a reference for the future-me.&lt;/p&gt;
&lt;h2&gt;Entropy and Prediction&lt;/h2&gt;
&lt;p&gt;Entropy as considered …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I will prefix this post by saying that none of the ideas here are new and its all well covered ground by now. Like much of this blog, I am mostly writing to clarify ideas and to serve as a reference for the future-me.&lt;/p&gt;
&lt;h2&gt;Entropy and Prediction&lt;/h2&gt;
&lt;p&gt;Entropy as considered in information theory, can be thought of as the number of possible values the each symbol can take on. A stream of perfectly random bits has maximal entropy because each symbol is equally likely to be a 1 or 0. If however we impose rules on such a binary stream, e.g. after 3x1s there must be a 0, then after a run of 3x1s, the next symbol must be a 0, and so the entropy of such a stream is reduced. This change in entropy can be considered &lt;em&gt;information&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Viewed through this lens, entropy and our ability to predict the next symbol, based on what has come before, are related concepts. If we can perfectly predict the next symbol every time, then the entropy of the a data stream is the entropy of the predictor, i.e. how many bits do we need to make the predictions.&lt;/p&gt;
&lt;h2&gt;Compression and Predictors&lt;/h2&gt;
&lt;p&gt;To compress a data stream is to reduce the number of bits required to represent towards the limit dictated by the entropy of the data stream. This can be done by looking for repeated symbols and using more efficient encoding for those symbols as is typically done with Huffman codes. A further refinement of this technique is to use a &lt;em&gt;predictor&lt;/em&gt; to predict the next symbol and encode the &lt;em&gt;difference&lt;/em&gt; between the actual symbol that occurs and the predicted symbol.&lt;/p&gt;
&lt;p&gt;To see why this is an improvement, consider a &lt;em&gt;perfect&lt;/em&gt; predictor - the only symbol we would need to encode is 0 which makes for very high compression ratios. In practice this rarely happens, but predictors do generally reduce the number of possible symbols. Consider the sequence &lt;code&gt;[10, 9, 8, 5, 3, 1]&lt;/code&gt;. This has 6 unique symbols we need to compress. However if we use a simple predictor that says "the next symbol is the same as the current symbol", then the difference is &lt;code&gt;[10, -1, -1, -3, -2, -2]&lt;/code&gt;, where we assume the first prediction is 0. This sequence of &lt;em&gt;difference from prediction&lt;/em&gt; only uses 4 symbols and is easier to compress.&lt;/p&gt;
&lt;p&gt;The use of predictors allows us to exploit correlation between symbols to achieve better compressions than simply using more efficient coding. Predictors can be continuously applied with a different predictor each time, to potentially exploit high levels of correlation. The use of predictors can be said to "decorrelate" the data because the ability to predict the next symbol in difference-from-prediction data stream is less than before. e.g. if we were apply the same predictor as before to &lt;code&gt;[10, -1, -1, -3, -2, -2]&lt;/code&gt; we get &lt;code&gt;[10, -11, 0, -2, 1, 0]&lt;/code&gt;, and now we have 5 symbols instead of the 4 we started with, i.e. use of the predictor was detrimental. Where as the original data had elements that &lt;em&gt;correlated&lt;/em&gt; to each other by difference of 1 or 2, the difference-from-prediction does not have this property. This also illustrates that the choice of predictor matters as a bad predictor can make things worse by trying to force correlations where non-exists.&lt;/p&gt;
&lt;p&gt;Predictors can be specified ahead of time, or "trained" on the data and transmitted along with the compressed data so the receiver can decompress it.&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="science"/></entry><entry><title>Adventures in Compressed DNG</title><link href="/adventures-in-compressed-dng.html" rel="alternate"/><published>2025-05-24T01:41:00+10:00</published><updated>2025-05-24T01:41:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2025-05-24:/adventures-in-compressed-dng.html</id><summary type="html">&lt;p&gt;I have been working with industrial cameras and frame-grabbers that simply gives me a dump of their sensor data. To make that data useful it needs to undergo &lt;a href&gt;demosaicing&lt;/a&gt;, ideally using one of the modern demosaic algorithms like &lt;a href="https://github.com/LuisSR/RCD-Demosaicing"&gt;RCD&lt;/a&gt; rather than simple interpolation or the rather outdated VNG. Unfortunately the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have been working with industrial cameras and frame-grabbers that simply gives me a dump of their sensor data. To make that data useful it needs to undergo &lt;a href&gt;demosaicing&lt;/a&gt;, ideally using one of the modern demosaic algorithms like &lt;a href="https://github.com/LuisSR/RCD-Demosaicing"&gt;RCD&lt;/a&gt; rather than simple interpolation or the rather outdated VNG. Unfortunately the latter are all that OpenCV supports.&lt;/p&gt;
&lt;p&gt;To gain access to more advanced demosaic algorithms and sophisticated image processing functions like colour calibration, micro-contrast, dehaze, etc, I encoded the raw &lt;a href="https://en.wikipedia.org/wiki/Color_filter_array"&gt;colour filter array (CFA)&lt;/a&gt; data into DNG using the &lt;a href="https://github.com/schoolpost/PiDNG"&gt;PiDNG&lt;/a&gt; library. With compression disabled this library produces DNGs which is accepted by &lt;a href="https://www.darktable.org/"&gt;darktable&lt;/a&gt;. However if I enable compression darktable is unable to open it.&lt;/p&gt;
&lt;p&gt;Running darktable from the command line, the following error is observed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mf"&gt;71.5724&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rawspeed&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dng&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;rawspeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;AbstractDngDecompressor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;decompress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Too&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encountered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Giving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="n"&gt;size_type&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nl"&gt;rawspeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;LJpegDecoder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="n"&gt;decodeScan&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;108&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Unsupported&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;predictor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This suggests that the predictor used is not supported. By editing the source code of PiDNG, predictor was set to 1 which results in yet another error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mf"&gt;10.7300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rawspeed&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compression&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dng&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;rawspeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;AbstractDngDecompressor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;decompress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Too&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;many&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encountered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Giving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;First&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;virtual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="n"&gt;size_type&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nl"&gt;rawspeed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nl"&gt;LJpegDecoder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="n"&gt;decodeScan&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;141&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Maximal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;multiple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LJpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;size&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This error happens because PiDNG uses an optimisation trick to improve the compression ratio. Consider a typical CFA pattern:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;RG
GB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The raw sensor data is essentially the above repeated horizontally and vertically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;RGRGRG
GBGBGB
RGRGRG
GBGBGB
RGRGRG
GBGBGB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Lossless_JPEG#Lossless_mode_of_operation"&gt;Lossless JPEG compressed by using a predictor&lt;/a&gt; that uses previous pixel values, including those in the previous row. Such a predictor work better if correlated values are closer together. So instead of saving the image as-is, the &lt;a href="https://kronometric.org/phot/processing/DNG/dng_spec_1.4.0.0.pdf"&gt;DNG specification (as of 1.4.0)&lt;/a&gt; allows the image data to be stored as an image that is twice as wide but halve as high (preserving the total number of pixels):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;RGRGRGGBGBGB 
RGRGRGGBGBGB
RGRGRGGBGBGB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this new image, correlated pixels are closer together. e.g. the first red pixel had no immediate neighbours that was also red, but now it has an immediate neighbour in the next row. The &lt;a href="https://github.com/darktable-org/rawspeed/pull/334"&gt;rawspeed library however doesn't support this optimisation trick (or predictors other than 1)&lt;/a&gt;, which to be fair is also useless with predictor 1, which only looks at the previous value on the same row. This trick is most useful with predictors that look at values from previous rows, e.g. mode 6 which is the default mode used by PiDNG.&lt;/p&gt;
&lt;p&gt;With another modification to the PiDNG library that encodes the sensor data as a JPEG image of the original size, we were able to produce a losslessly compressed DNG file that darktable opens. The compression ratio isn't as good - 80% vs 75%. Hopefully darktable will gain support for predictors 2-7 and we can get better compression. In the meantime I cleaned up the changes to PiDNG and have submitted a &lt;a href="https://github.com/schoolpost/PiDNG/pull/94"&gt;PR&lt;/a&gt; which will hopefully be accepted.&lt;/p&gt;
&lt;h2&gt;Rant&lt;/h2&gt;
&lt;p&gt;DNG v1.4.0 was released in 2012, a time when DEFLATE compression in TIFF files was widely used yet for some reason the DNG specification restricts its use to floating point image data with estoic lossless JPEG, defined 20 years ago in 1992, being the only other lossless compression option. It is not until 2023, with DNG v1.7.0, that JPEG-XL is added for integer image data. Unfortunately JPEG-XL is exotic enough that darktable still doesn't support it in 2025. Why we couldn't have allowed Deflate for integer image data is beyond me. So much space could have been be saved.&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="oss"/><category term="code"/><category term="python"/></entry><entry><title>Python One-liner for Local QR Code Decoding</title><link href="/python-one-liner-for-local-qr-code-decoding.html" rel="alternate"/><published>2025-04-10T03:07:00+10:00</published><updated>2025-04-10T03:07:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2025-04-10:/python-one-liner-for-local-qr-code-decoding.html</id><summary type="html">&lt;p&gt;Because KeepassXC lacks the ability to decode QR code for TOTP setup and not all MFA implementations show the required secret in text format, I use the following snipet to read the QR code information locally:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;from cv2 import QRCodeDetector; from PIL.ImageGrab import grabclipboard; import numpy as …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Because KeepassXC lacks the ability to decode QR code for TOTP setup and not all MFA implementations show the required secret in text format, I use the following snipet to read the QR code information locally:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;from cv2 import QRCodeDetector; from PIL.ImageGrab import grabclipboard; import numpy as np; print(QRCodeDetector().detectAndDecode(np.array(grabclipboard()))[0])&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While there are many websites which can do the same, the TOTP secret is sensitive information that shouldn't be transmitted willy nilly to random websites.&lt;/p&gt;
&lt;p&gt;You will need the following libraries installed: &lt;code&gt;python-opencv&amp;gt;4, numpy, pillow&lt;/code&gt;. If you use &lt;code&gt;uv&lt;/code&gt; then it is possible to have this as a nice script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env -S uv run --quiet --script&lt;/span&gt;
&lt;span class="c1"&gt;# /// script&lt;/span&gt;
&lt;span class="c1"&gt;# requires-python = &amp;quot;&amp;gt;=3.11&amp;quot;&lt;/span&gt;
&lt;span class="c1"&gt;# dependencies = [&lt;/span&gt;
&lt;span class="c1"&gt;#     &amp;quot;numpy&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;#     &amp;quot;pillow&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;#     &amp;quot;opencv-python&amp;gt;3&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;# ]&lt;/span&gt;
&lt;span class="c1"&gt;# ///&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;cv2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;QRCodeDetector&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;PIL.ImageGrab&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grabclipboard&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grabclipboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Clipboard does not contain an image&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;


&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;QRCodeDetector&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;detectAndDecode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;im&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# QR codes cannot encode the empty string (apparently)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;No QR code detected&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Put this in your path somewhere and you can execute it like any other script and &lt;code&gt;uv&lt;/code&gt; will handle installing depedencies etc.&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="software"/><category term="oss"/></entry><entry><title>PIO and Interrupts</title><link href="/pio-and-interrupts.html" rel="alternate"/><published>2024-08-11T03:53:00+10:00</published><updated>2024-08-11T03:53:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2024-08-11:/pio-and-interrupts.html</id><summary type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;I want to be able to raise system level interrupts from PIO programs and there aren’t too many &lt;a href="https://github.com/raspberrypi/pico-examples/blob/master/pio/uart_rx/uart_rx_intr.c"&gt;examples of this&lt;/a&gt;, so here is my simple contribution.&lt;/p&gt;
&lt;h1&gt;PIO program&lt;/h1&gt;
&lt;p&gt;First, the PIO program, which simply waits for a pin to change and then immediately raises PIO IRQ 0 …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;I want to be able to raise system level interrupts from PIO programs and there aren’t too many &lt;a href="https://github.com/raspberrypi/pico-examples/blob/master/pio/uart_rx/uart_rx_intr.c"&gt;examples of this&lt;/a&gt;, so here is my simple contribution.&lt;/p&gt;
&lt;h1&gt;PIO program&lt;/h1&gt;
&lt;p&gt;First, the PIO program, which simply waits for a pin to change and then immediately raises PIO IRQ 0.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;.program&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;irq_example&lt;/span&gt;
&lt;span class="na"&gt;.wrap_target&lt;/span&gt;

&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;pin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;; wait for a 0 on IN pin 0&lt;/span&gt;
&lt;span class="nf"&gt;irq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nowait&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;; raise PIO IRQ 0&lt;/span&gt;

&lt;span class="na"&gt;.wrap&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compile this with &lt;code&gt;pioasm&lt;/code&gt; then &lt;code&gt;#include&lt;/code&gt; the &lt;code&gt;.h&lt;/code&gt; in your C program.&lt;/p&gt;
&lt;h1&gt;C Program&lt;/h1&gt;
&lt;h2&gt;Interrupt Setup&lt;/h2&gt;
&lt;p&gt;There are four system level interrupts related to PIO: &lt;code&gt;PIO0_IRQ_0&lt;/code&gt;, &lt;code&gt;PIO0_IRQ_1&lt;/code&gt;, &lt;code&gt;PIO1_IRQ_0&lt;/code&gt;, &lt;code&gt;PIO1_IRQ_1&lt;/code&gt;. We shall use &lt;code&gt;PIO0_IRQ_0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First we attach an interrupt handler to &lt;code&gt;PIO0_IRQ_0&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;void isr(void) {
    // clear PIO IRQ 0 that was raised by irq nowait 0
    pio_interrupt_clear(pio0, 0);
}

irq_add_shared_handler(PIO0_IRQ_0,
                       isr,
                       PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;It is important that &lt;code&gt;pio_interrupt_clear()&lt;/code&gt; is called otherwise the CPU will lock up constantly executing the interrupt handler (aka ISR - interrupt service routine)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We then enable the interrupt:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;irq_set_enabled(PIO0_IRQ_0, true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally we configure &lt;code&gt;PIO0_IRQ_0&lt;/code&gt; to be triggered when PIO IRQ 0 is raised:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pio_set_irq0_source_enabled(pio0, pis_interrupt0, true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The functions used above are described in the &lt;a href="https://www.raspberrypi.com/documentation/pico-sdk/index_doxygen.html"&gt;Pico C SDK documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;PIO Setup&lt;/h2&gt;
&lt;p&gt;The PIO program can now by installed the usual way by first setting up the state machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;uint sm = pio_claim_unused_sm(pio0, true);
uint offset = pio_add_program(pio0, &amp;amp;irq_example_program);
pio_sm_config cfg = irq_example_program_get_default_config(offset);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Configure and connect GPIO to the state machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// connect GP 2 to IN of state machine&lt;/span&gt;
&lt;span class="n"&gt;sm_config_set_in_pins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// it is an input pin&lt;/span&gt;
&lt;span class="n"&gt;pio_sm_set_consecutive_pindirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pio0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// we want pull up on the pin&lt;/span&gt;
&lt;span class="n"&gt;gpio_pull_up&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we are ready to start the state machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pio_sm_init(pio0, sm, offset, &amp;amp;cfg);
pio_sm_set_enabled(pio0, sm, true);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"/><category term="electronics"/><category term="c"/><category term="arduino"/><category term="asm"/><category term="oss"/></entry><entry><title>PIO ASM and PlatformIO</title><link href="/pio-asm-and-platformio.html" rel="alternate"/><published>2024-08-11T03:25:00+10:00</published><updated>2024-08-11T03:25:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2024-08-11:/pio-asm-and-platformio.html</id><summary type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;h2&gt;PIO&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf"&gt;RP2040&lt;/a&gt; has two &lt;a href="https://www.raspberrypi.com/news/what-is-pio/"&gt;programmable IO (PIO) blocks&lt;/a&gt;, each capable of executing 4 programs in parallel. This allows the RP2040 great flexibility in mix and matching different protocols. Want 3x CANBUS and 1xSPI? RP2040 got you. Want 5xI2C instead? That’s cool too. It is a very flexible …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;h2&gt;PIO&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf"&gt;RP2040&lt;/a&gt; has two &lt;a href="https://www.raspberrypi.com/news/what-is-pio/"&gt;programmable IO (PIO) blocks&lt;/a&gt;, each capable of executing 4 programs in parallel. This allows the RP2040 great flexibility in mix and matching different protocols. Want 3x CANBUS and 1xSPI? RP2040 got you. Want 5xI2C instead? That’s cool too. It is a very flexible approach vs having hardwired peripherals and since PIO execute independently of the CPU, nicer and faster than using the CPU to do bitbang.&lt;/p&gt;
&lt;p&gt;PIOs are essentially hyperspecialised CPUs and they have their own assembly language which is parsed by a program called &lt;code&gt;pioasm&lt;/code&gt;, part of the &lt;a href="https://github.com/raspberrypi/pico-sdk"&gt;&lt;code&gt;pico-sdk&lt;/code&gt;&lt;/a&gt;. &lt;code&gt;pioasm&lt;/code&gt; converts PIO programs in assembly into C-headers which can then be &lt;code&gt;#included&lt;/code&gt; and used. Typically you have your PIO programs in a &lt;code&gt;.pioasm&lt;/code&gt; file which is then transpiled into a &lt;code&gt;.h&lt;/code&gt; file by &lt;code&gt;pioasm&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;PlatformIO&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://platformio.org/"&gt;PlatformIO&lt;/a&gt; is a very nice platform for doing embedded development. It nicely packages up all the toolchains and dependencies for you and sets everything up all neat and tidy.&lt;/p&gt;
&lt;h1&gt;PlatformIO and &lt;code&gt;pioasm&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;While PlatformIO knows how to compile C code, it doesn’t natively support &lt;code&gt;pioasm&lt;/code&gt;, which means you need to remember to manually invoke &lt;code&gt;pioasm&lt;/code&gt; before building with PlatformIO, or configure PlatformIO to run a pre-build step that runs &lt;code&gt;pioasm&lt;/code&gt; against all &lt;code&gt;.pioasm&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively, one can use &lt;code&gt;make&lt;/code&gt; which I have opted to do since it &lt;em&gt;feels&lt;/em&gt; natural - after all &lt;code&gt;make&lt;/code&gt; is designed for this kind of work.&lt;/p&gt;
&lt;p&gt;With the following &lt;code&gt;Makefile&lt;/code&gt;, all &lt;code&gt;.pioasm&lt;/code&gt; files are compiled into their &lt;code&gt;.h&lt;/code&gt; counter-part prior to building the program. The &lt;code&gt;Makefile&lt;/code&gt; wraps common PlatformIO tasks to provide additional convenience.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;PIOASM&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pioasm&lt;/span&gt;

&lt;span class="o"&gt;%.&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/%.&lt;/span&gt;&lt;span class="n"&gt;pioasm&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PIOASM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/$&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;

&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pio_trigger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;pio&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;

&lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;pio&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This script assumes your source code is in &lt;code&gt;/src&lt;/code&gt; and you have a copy of &lt;code&gt;pioasm&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;Building &lt;code&gt;pioasm&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;Because I use the community developed &lt;a href="https://arduino-pico.readthedocs.io/en/latest/index.html"&gt;&lt;code&gt;arduino-pico&lt;/code&gt;&lt;/a&gt; core, a copy of &lt;code&gt;pico-sdk&lt;/code&gt; was already available in &lt;code&gt;$HOME/.platformio/packages/framework-arduinopico/pico-sdk/&lt;/code&gt;, including the &lt;code&gt;pioasm&lt;/code&gt; source code. &lt;code&gt;pioasm&lt;/code&gt; can then be built as follows (assuming you are on a unix-like):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;HOME&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;platformio&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;framework&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;arduinopico&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pico&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pioasm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="n"&gt;cmake&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="n"&gt;make&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will produce the &lt;code&gt;pioasm&lt;/code&gt; binary in the &lt;code&gt;build/&lt;/code&gt; directory. You can leave it there or move it.&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Estimating a Supernova's Brightness as an Amateur</title><link href="/estimating-a-supernovas-brightness-as-an-amateur.html" rel="alternate"/><published>2024-01-23T12:11:00+11:00</published><updated>2024-01-23T12:11:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2024-01-23:/estimating-a-supernovas-brightness-as-an-amateur.html</id><summary type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;2023rve is the designation given to a Type II supernova discovered on 2023-09-08 by Mohammad Odeh from UAE. It appears to be part of NGC 1097, a galaxy 45 million light years away. Due to it’s brightness, 2023rve was visible to budget amateur astronomers/astrophotographers like myself.&lt;/p&gt;
&lt;p&gt;Below …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;2023rve is the designation given to a Type II supernova discovered on 2023-09-08 by Mohammad Odeh from UAE. It appears to be part of NGC 1097, a galaxy 45 million light years away. Due to it’s brightness, 2023rve was visible to budget amateur astronomers/astrophotographers like myself.&lt;/p&gt;
&lt;p&gt;Below is my first image of 2023rve.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/photos/sentientintelligence/53197562319/" title="2023rve"&gt;&lt;img src="/media/786960_53197562319_50421e7b71_c.jpg" width="600" alt="2023rve" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a stacked image consisting of 64x60s exposures captured using an unmodified Canon 800D attached to an Evostar 72ED. I was and continue to be very excited about this image because supernovas occur but rarely and are generally out of reach for budget setups like mine. Catching glimpse of one is not unlike seeing an unicorn.&lt;/p&gt;
&lt;h1&gt;Light Curves&lt;/h1&gt;
&lt;p&gt;2023rve is a &lt;a href="https://en.wikipedia.org/wiki/Supernova#Type_II"&gt;type II supernova&lt;/a&gt;, and its light curve will look like one of the following depending on its subclassification (II-P, II-L, IIn or IIb).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Type II-P and type II-L supernova lightcurves" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Comparative_supernova_type_light_curves.png/640px-Comparative_supernova_type_light_curves.png"&gt;&lt;/p&gt;
&lt;p&gt;It occurred to me then that with sufficient images I can have a go at generating such a light curve and figure out what kind of supernova 2023rve is! This is a particular exciting idea to me because it takes supernovas from the realm of theory (knowing about them) into reality (studying them).&lt;/p&gt;
&lt;p&gt;In the time since then, I managed 4 captures in total, including the one above, and this post documents my efforts in estimating the magnitude of 2023rve from my data and using that to construct a light curve.&lt;/p&gt;
&lt;h1&gt;General Approach&lt;/h1&gt;
&lt;p&gt;The idea is to calibrate my data, which are 60 second exposures of 2023rve, against stars of known visual magnitude. By comparing the pixel values that make up 2023rve vs these calibration stars, I can estimate its apparent visual magnitude. Then, making the assumption 2023rve is part of NGC1097, we can use the distance to NGC1097 to calculate the absolute magnitude of 2023rve and generate a light curve.&lt;/p&gt;
&lt;h1&gt;Identifying Stars&lt;/h1&gt;
&lt;p&gt;The first step is to find stars and their known magnitudes. While bright stars such as Rigel or Sirius have well known magnitudes, the stars in the vicinity of NGC1097 are less well known and unnamed. In order to look up stars in astronomical databases, we need their right-ascension (RA) and declination (DEC) coordinates. These coordinates serve the same purpose as GPS coordinates of latitude and longitude: they unique identify a position in the sky.&lt;/p&gt;
&lt;p&gt;To locate our stars, I loaded my images into &lt;a href="https://siril.org/"&gt;Siril&lt;/a&gt; and carried out &lt;a href="https://siril.readthedocs.io/en/latest/astrometry/platesolving.html"&gt;platesolving&lt;/a&gt;, a method of locating images within the sky by looking at the pattern of the stars within the image.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/gp/sentientintelligence/E56975SNJ8" title="Screenshot 2024-01-23 at 12.11.39 pm"&gt;&lt;img src="/media/c68e63_53480520027_7f91185f94_w.jpg" width="318" height="400" alt="Screenshot 2024-01-23 at 12.11.39 pm" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once platesolving is completed, I saved the file as a FITS file which embeds the coordinate information into the file metadata. I then open the FITS file in &lt;a href="https://www.astro.louisville.edu/software/astroimagej/"&gt;AstroImageJ&lt;/a&gt; and by manually adjusting the upper and lower limits on the histogram in the image viewer and zooming in, I am able to get a good view of NGC1097.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/gp/sentientintelligence/03K34633a3" title="Screenshot 2024-01-23 at 12.50.16 pm"&gt;&lt;img src="/media/3d0bac_53481442531_c201484c4c_w.jpg" width="365" height="400" alt="Screenshot 2024-01-23 at 12.50.16 pm" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By right clicking on the image, a link to SIMBAD will open which allows all known stellar objects in the vicinity to be queried. Using this, three objects with known visual magnitudes were identified and annotated.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/gp/sentientintelligence/Dy6i2455Wf" title="Screenshot 2024-01-23 at 12.49.26 pm"&gt;&lt;img src="/media/bb2d73_53481853235_24a1fb7f9b_w.jpg" width="364" height="400" alt="Screenshot 2024-01-23 at 12.49.26 pm" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;These are our reference stars and their visual magnitude is tabulated below.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;th&gt;Vmag&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CD-30 1031&lt;/td&gt;
&lt;td&gt;10.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TYC 7011-484-1&lt;/td&gt;
&lt;td&gt;11.39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TYC 7011-1028-1&lt;/td&gt;
&lt;td&gt;12.15&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;Measuring Brightness&lt;/h1&gt;
&lt;p&gt;In order to relate the brightness of these stars to the measure pixel values, I used AstroImageJ’s single-aperture photometry tool, which samples a central circular region and an annulus around it. The central circular region should just fit the star while the annulus should contain only background. The background pixel value is estimated from the pixels within the annulus and subtracted from the stellar pixel values. This value is reported as &lt;code&gt;Int Cnts&lt;/code&gt;. This measurement was done on each of the reference stars and 2023rve, e.g.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/gp/sentientintelligence/7D9H49Mtu8" title="Screenshot 2024-01-22 at 12.32.31 pm"&gt;&lt;img src="/media/f4c159_53481726964_2e239c3458_w.jpg" width="366" height="400" alt="Screenshot 2024-01-22 at 12.32.31 pm" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Deriving Visual Magnitude&lt;/h1&gt;
&lt;p&gt;Tabulating the &lt;code&gt;Int Cnts&lt;/code&gt; obtained across the 4 observations produces the following:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;CD-30 1031&lt;/th&gt;
&lt;th&gt;TYC 7011-484-1&lt;/th&gt;
&lt;th&gt;TYC 7011-1028-1&lt;/th&gt;
&lt;th&gt;2023rve&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-18&lt;/td&gt;
&lt;td&gt;1.09E+06&lt;/td&gt;
&lt;td&gt;4.54E+05&lt;/td&gt;
&lt;td&gt;2.43E+05&lt;/td&gt;
&lt;td&gt;2.77E+04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-24&lt;/td&gt;
&lt;td&gt;1.09E+06&lt;/td&gt;
&lt;td&gt;4.67E+05&lt;/td&gt;
&lt;td&gt;2.60E+05&lt;/td&gt;
&lt;td&gt;2.49E+04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-11-18&lt;/td&gt;
&lt;td&gt;9.65E+05&lt;/td&gt;
&lt;td&gt;4.32E+05&lt;/td&gt;
&lt;td&gt;2.64E+05&lt;/td&gt;
&lt;td&gt;1.20E+04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-01-22&lt;/td&gt;
&lt;td&gt;1.14E+06&lt;/td&gt;
&lt;td&gt;5.47E+05&lt;/td&gt;
&lt;td&gt;2.73E+05&lt;/td&gt;
&lt;td&gt;1.06E+03&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It is quite pleasing that the &lt;code&gt;Int Cnts&lt;/code&gt; values for the three reference stars are relatively stable, particularly as I am not using an uncooled sensor nor did I control for atmospheric conditions. Of the three reference stars, &lt;code&gt;TYC 7011-1028-1&lt;/code&gt; had the fewest saturating pixels and was the most stable over time, and was chosen as the reference against which to measure 2023rve’s brightness:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;TYC 7011-1028-1&lt;/th&gt;
&lt;th&gt;2023rve&lt;/th&gt;
&lt;th&gt;(2023rve) / (TYC 7011-1028-1)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-18&lt;/td&gt;
&lt;td&gt;2.43E+05&lt;/td&gt;
&lt;td&gt;2.77E+04&lt;/td&gt;
&lt;td&gt;0.114&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-24&lt;/td&gt;
&lt;td&gt;2.60E+05&lt;/td&gt;
&lt;td&gt;2.49E+04&lt;/td&gt;
&lt;td&gt;0.096&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-11-18&lt;/td&gt;
&lt;td&gt;2.64E+05&lt;/td&gt;
&lt;td&gt;1.20E+04&lt;/td&gt;
&lt;td&gt;0.045&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-01-22&lt;/td&gt;
&lt;td&gt;2.73E+05&lt;/td&gt;
&lt;td&gt;1.06E+03&lt;/td&gt;
&lt;td&gt;0.004&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;By expressing 2023rve’s brightness in terms of &lt;code&gt;TYC 7011-1028-1&lt;/code&gt; I am implicit assuming the my sensor’s response is approximately linear for the brightness being measured.&lt;/p&gt;
&lt;p&gt;Magnitudes are logarithms of ratios, so the brightness ratio in the table above turns into a difference in magnitude given by &lt;code&gt;mag_diff=-2.5log10(x))&lt;/code&gt; where &lt;code&gt;x&lt;/code&gt; are the values in the final column. By adding this value from the visual magnitude of &lt;code&gt;TYC 7011-1028-1&lt;/code&gt; we arrive at an estimated visual magnitude for 2023rve:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;(2023rve) / (TYC 7011-1028-1)&lt;/th&gt;
&lt;th&gt;mag_diff&lt;/th&gt;
&lt;th&gt;Vmag&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-18&lt;/td&gt;
&lt;td&gt;0.114&lt;/td&gt;
&lt;td&gt;2.355&lt;/td&gt;
&lt;td&gt;14.505&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-24&lt;/td&gt;
&lt;td&gt;0.096&lt;/td&gt;
&lt;td&gt;2.545&lt;/td&gt;
&lt;td&gt;14.695&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-11-18&lt;/td&gt;
&lt;td&gt;0.045&lt;/td&gt;
&lt;td&gt;3.355&lt;/td&gt;
&lt;td&gt;15.505&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-01-22&lt;/td&gt;
&lt;td&gt;0.004&lt;/td&gt;
&lt;td&gt;6.030&lt;/td&gt;
&lt;td&gt;18.180&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h1&gt;Verification&lt;/h1&gt;
&lt;p&gt;The estimated visual magnitude of 2023rve looks quite reasonable, but is it correct? Thankfully professional astronomers have made their own measurements which I have collected below:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Vmag&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-06&lt;/td&gt;
&lt;td&gt;14.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-11&lt;/td&gt;
&lt;td&gt;13.9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-16&lt;/td&gt;
&lt;td&gt;14.43&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-09-24&lt;/td&gt;
&lt;td&gt;14.390&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2023-11-15&lt;/td&gt;
&lt;td&gt;15.500&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-01-06&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Sources:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.wis-tns.org/astronotes/astronote/2023-247"&gt;https://www.wis-tns.org/astronotes/astronote/2023-247&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rochesterastronomy.org/supernova.html#2023rve"&gt;https://www.rochesterastronomy.org/supernova.html#2023rve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.flickr.com/photos/snimages/53209027493/in/photostream/"&gt;https://www.flickr.com/photos/snimages/53209027493/in/photostream/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gsaweb.ast.cam.ac.uk/alerts/alert/Gaia23cmp/"&gt;http://gsaweb.ast.cam.ac.uk/alerts/alert/Gaia23cmp/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Compared against these, my visual magnitudes estimates compare quite favourably! I am pleasantly surprised how well things worked out. My last measurement, on 2024-01-22, stands out by how much it differs. It is also the measurement I have the least confidence in as by that point I could no longer reliably identify 2023rve in a single 60s exposure. I have some ideas here: take longer exposures or stack my exposures carefully (keeping values linear) and estimate from the stacked image.&lt;/p&gt;
&lt;h1&gt;Absolute Magnitude&lt;/h1&gt;
&lt;p&gt;The conversion to absolute magnitude is &lt;a href="https://en.wikipedia.org/wiki/Absolute_magnitude#Apparent_magnitude"&gt;quite straight-forward&lt;/a&gt; as is the subsequent plotting.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.flickr.com/gp/sentientintelligence/kA3Y4216LX" title="Screenshot 2024-01-23 at 1.43.29 pm"&gt;&lt;img src="/media/6f2845_53481520981_5dc983a017_z.jpg" width="640" height="354" alt="Screenshot 2024-01-23 at 1.43.29 pm" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Note that because I don’t know when peak brightness occurred, I am using days-since-discovery instead.&lt;/p&gt;
&lt;h1&gt;Type II Classification&lt;/h1&gt;
&lt;p&gt;I don’t think there is enough data yet to definitively say what subtype 2023rve is. More data points will decide the matter and I look forward to the next set of clear skies so I can continue this effort.&lt;/p&gt;</content><category term="posts"/><category term="astronomy"/></entry><entry><title>On NS*DateFormatters</title><link href="/on-nsdateformatters.html" rel="alternate"/><published>2023-12-23T01:16:00+11:00</published><updated>2023-12-23T01:16:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-12-23:/on-nsdateformatters.html</id><summary type="html">&lt;p&gt;There now exists &lt;code&gt;NSDateFormatter&lt;/code&gt; and &lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; and their behaviour when a timezone is not set is not the same: &lt;code&gt;NSDateFormatter&lt;/code&gt; produces strings formatted for &lt;strong&gt;local time&lt;/strong&gt; while &lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; produces string formatted for &lt;strong&gt;UTC&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As an example, given a date-time of &lt;code&gt;2000-12-31T23:00:00Z&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSDateFormatter&lt;/code&gt; with no timezone set and full …&lt;/p&gt;</summary><content type="html">&lt;p&gt;There now exists &lt;code&gt;NSDateFormatter&lt;/code&gt; and &lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; and their behaviour when a timezone is not set is not the same: &lt;code&gt;NSDateFormatter&lt;/code&gt; produces strings formatted for &lt;strong&gt;local time&lt;/strong&gt; while &lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; produces string formatted for &lt;strong&gt;UTC&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As an example, given a date-time of &lt;code&gt;2000-12-31T23:00:00Z&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSDateFormatter&lt;/code&gt; with no timezone set and full styles:&lt;br&gt;
Monday, January 1, 2001 at 10:00:00 AM Australian Eastern Daylight Time&lt;/p&gt;
&lt;p&gt;&lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; with no timezone set:&lt;br&gt;
2000-12-31T23:00:00Z&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;NSDateFormatter&lt;/code&gt; "applies" my local timezone automatically whereas &lt;code&gt;NSISO8601DateFormatter&lt;/code&gt; doesn't. Sidebar: it seems that while &lt;code&gt;NSDate&lt;/code&gt; carries no timezone information, it is always interpreted as UTC time.&lt;/p&gt;</content><category term="posts"/><category term="objective-c"/><category term="code"/></entry><entry><title>DIY EQMod Direct USB Cable</title><link href="/diy-eqmod-direct-usb-cable.html" rel="alternate"/><published>2023-10-27T04:34:00+11:00</published><updated>2023-10-27T04:34:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-10-27:/diy-eqmod-direct-usb-cable.html</id><summary type="html">&lt;p&gt;I am in the process of resurrecting my Eq5 Pro so it is compatible with ASIAir Mini. The first step is to build an EQMod Direct USB cable. While it is possible to buy one pre-made, since I had all the parts I decided to build it myself.&lt;/p&gt;
&lt;p&gt;Based on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I am in the process of resurrecting my Eq5 Pro so it is compatible with ASIAir Mini. The first step is to build an EQMod Direct USB cable. While it is possible to buy one pre-made, since I had all the parts I decided to build it myself.&lt;/p&gt;
&lt;p&gt;Based on the &lt;a href="https://eq-mod.sourceforge.net/tutindex.html"&gt;reference document&lt;/a&gt; I need to make an single-ended RJ45 cable. I followed &lt;a href="https://satoms.com/ethernet-cable-pinouts/"&gt;T-568A colour scheme&lt;/a&gt;:&lt;/p&gt;
&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/28c0aa_RJ45_Pinout.gif" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoIKn1uYcoaL1b2KpWpO0tvvzG2RSswRZJrb0TZuzc_IksAQCVe2FiPZBrzUumdypSy6YrSsZ8zk9KSoG7KL_dPHoU29iRol_8_w1-b5ehoRCGHC4nKx6kT5enpSHVBoO_c-mFB4OCFnMJ5KRcu5Q68lJvVVEGA5L8ZW6bEcU20ndhtSGheSZMAw/s320/RJ45-Pinout.gif" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Based on this colour scheme, the connection to a USB-UART adapter is as follows:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;RJ45&lt;/th&gt;
&lt;th&gt;Colour&lt;/th&gt;
&lt;th&gt;USB-UART&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Blue&lt;/td&gt;
&lt;td&gt;Ground&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Blue-White&lt;/td&gt;
&lt;td&gt;RXI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Orange&lt;/td&gt;
&lt;td&gt;TXO&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Plug the RJ45 end of the cable into the hand-controller port on the control box and the other end into the ASIAir Mini. Then power up the ASIAir Mini as usual and use one of the 12V outputs to power the SynScan. Make sure to switch on the SynScan as it has its own power switch. After this select EQMod for the mount model and leave the baudrate at the default value of 9600. Tap the enable-toggle-switch and the ASIAir Mini will attempt to connect to the mount. After a successful connection you should be able to manually slew the mount in RA and DEC in Preview mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I have to power up the SynScan &lt;em&gt;after&lt;/em&gt; the ASIAir has fully booted (made it's beeping noises) in order for them to communicate successfully. If both are powered up at the same time, something goes awry and the ASIAir Mini will not be able to connect.&lt;/p&gt;</content><category term="posts"/><category term="electronics"/><category term="diy"/><category term="astronomy"/></entry><entry><title>Build Log: SCD41 CO2 Sensor</title><link href="/build-log-scd41-co2-sensor.html" rel="alternate"/><published>2023-09-17T14:21:00+10:00</published><updated>2023-09-17T14:21:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2023-09-17:/build-log-scd41-co2-sensor.html</id><summary type="html">&lt;p&gt;CO2 concentration is a proxy for how well a space, especially an enclosed one, is ventillated. To this end I build a quick-n-dirty CO2 sensor using a SCD41 breakout board from pimoroni and bits and pieces I had in the workshop.&lt;/p&gt;
&lt;p&gt;Took the opportunity to practice making enclosures, especially for …&lt;/p&gt;</summary><content type="html">&lt;p&gt;CO2 concentration is a proxy for how well a space, especially an enclosed one, is ventillated. To this end I build a quick-n-dirty CO2 sensor using a SCD41 breakout board from pimoroni and bits and pieces I had in the workshop.&lt;/p&gt;
&lt;p&gt;Took the opportunity to practice making enclosures, especially for an irregularly shaped circuit. The enclosure was designed in FreeCAD by taking a picture of the circuit then importing it as a reference image. After correct for scale the designed enclosure was reasonable accurate, needing only some small tweaks to dimensions to correct forperspective distortion. The result was then 3D printed on my FF Creator Pro.&lt;/p&gt;
&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/d2f688_IMG_5112_202.JPG" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUOXXzSGlv5FaZTrdq5B7_Ir4wJXktqnZ0A4V1-4Ad1DxzpURMA26ZfDJb3HCRu8XhaVYP_-uGkEWLcy9K1uwygfgIXjOQwi_fjX83FfwLjceu92Obntm3-F9xhbh7CLYPxas_w1hxaB1R8cHeX2J3kFxblukgfL0L8LAo87JOzfCME-YbPCFD9w/s320/IMG_5112%202.JPG" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The enclosure provides openings for a button (currently unused), a "cage" for the CO2 sensor, display and micro-USB port.&lt;/p&gt;
&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/39eb97_IMG_5100_203.JPG" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9NM0iiKZn7wcmLu9-EOrXo17VNcKBu9ElX3lmDNRoVhUwIu9GeDSsGzH5XVnwZdNTsfB8xoM-6N2Qkfbl21OvwUAIdcYM9aJDTokL8_YOgWJrvPx8ct_uiZ3mxP6_PYFmGBXuOW7S2YtW9g_Nnv9qkoclxDoO-LpU9kAmNVIGxHOyyRdch9yVNw/s320/IMG_5100%203.JPG" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;In addition to practicing painting techniques, I also wanted to try new ways of "labelling" my projects. Water-slide decals are widely used in model kits, and it turns out you can buy blank sheets with which to make your own decals with! I picked a cheap'ish option off Amazon. Just search for "water slide decal clear laser". Once they arrived it was a simple matter of designing the decals in inkscape, printing it out and cutting them to size. To complete the build, a plastic primer was applied, followed by colour coats, then a clear coat was applied, followed by the decal, followed by 2 more layers of clear coat.&lt;/p&gt;
&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/84c28b_IMG_5111_203.JPG" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0cQ-AwSGDFaZEnbQBIc0M3NW_-amJ_wEv-Tfk2VZM4zRunHsQUfnSp49iI6-6mZDIZzpoDwCMDJz-tvBVnxPV4ciwZ7krJN4pkOdP3gp5Wd_DnfIW91DxVdZ9VFc4WmHKgL5Kw2r98mh-Lw3sUrHD-wWu3cEBuRH981fgCBqUlXNXK8frP18zpQ/s320/IMG_5111%203.JPG" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/f81244_IMG_5114_202.JPG" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVzPWv4G_EXCD7N2fmojh8Ew3T8yDpSuE55tEWp-rhDe76fEaotpl1qgKSoKuUB599JvxgoKMWFi3S6zbCTRXengGAPtcKg0lOg9X3YMtEVauMqmaCmJPEB4YXxygI6ekRomMhX2evG9uyAjodDP69DECOEVvWRkUcWZ6cvbpKtCRPYs1Xnv_TmA/s320/IMG_5114%202.JPG" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both;"&gt;

&lt;a href="/media/539d69_IMG_5119.JPG" style="display: block; padding: 1em 0; text-align: center;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxXw39r07Qrrq1AGrqLpkqoMTyUm5MSO9H3dYnoLVVwfO_gJzebyM-zVB5r7LTZNAVzujQX9uhKcW6_Do3sughsl5hNOZqp8M4ZacS7b6z0C8540E9ynF7tdAxdWcgfUtl7JSFiKUmWVT12nfCennzLFi0b-pzGjttMaovmt1kNMHIZr7Z3oDxZw/s320/IMG_5119.JPG" data-border="0" width="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Overall quite happy with the outcome! Could have done more sanding before applying paint to hide the layer lines better and the a matte coat I think would have worked better. Nonetheless the decal idea worked out well and I think it will be my goto - a big improvement over permanent markers.&lt;/p&gt;</content><category term="posts"/><category term="electronics"/><category term="arduino"/><category term="diy"/><category term="cad"/><category term="freecad"/><category term="3dprinting"/></entry><entry><title>Notes on DietPi</title><link href="/notes-on-dietpi.html" rel="alternate"/><published>2023-07-28T07:53:00+10:00</published><updated>2023-07-28T07:53:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2023-07-28:/notes-on-dietpi.html</id><content type="html">&lt;p&gt;Recently decided to resurrect a RPI Model B (&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Unexpected Latency in Tinyproxy</title><link href="/unexpected-latency-in-tinyproxy.html" rel="alternate"/><published>2023-03-28T20:58:00+11:00</published><updated>2023-03-28T20:58:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-03-28:/unexpected-latency-in-tinyproxy.html</id><summary type="html">&lt;p&gt;I love &lt;a href="https://tinyproxy.github.io/"&gt;&lt;code&gt;tinyproxy&lt;/code&gt;&lt;/a&gt;, it is simple to setup and more than enough for my needs. Recently however I noticed that some clients were experiencing unexpected long delays when doing something as simple as &lt;code&gt;curl google.com&lt;/code&gt;. After some sleuthing, I tracked it down to the fact I had&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;LogLevel Info …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;I love &lt;a href="https://tinyproxy.github.io/"&gt;&lt;code&gt;tinyproxy&lt;/code&gt;&lt;/a&gt;, it is simple to setup and more than enough for my needs. Recently however I noticed that some clients were experiencing unexpected long delays when doing something as simple as &lt;code&gt;curl google.com&lt;/code&gt;. After some sleuthing, I tracked it down to the fact I had&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;LogLevel Info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;in my config. When this is set &lt;code&gt;tinyproxy&lt;/code&gt; produces log entries such as&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;CONNECT&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Mar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;41&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;7023&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;descriptor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;123.123.123.123&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;the &lt;code&gt;[unknown]&lt;/code&gt; is due to &lt;code&gt;tinyproxy&lt;/code&gt; attempting and failing to resolve the connecting IP into a hostname. It is this attempt to map IP to hostname that is causing the latencies observed. To resolve this I added offending IP to &lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;123.123.123.123&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;some&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;with the above entry the latency went away and the log entries now look like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;CONNECT&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nv"&gt;Mar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;:&lt;span class="mi"&gt;39&lt;/span&gt;:&lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;[&lt;span class="mi"&gt;6879&lt;/span&gt;]:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;descriptor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;some&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;[&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;123&lt;/span&gt;]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"/><category term="software"/><category term="oss"/></entry><entry><title>Conda and Slow Proxies</title><link href="/conda-and-slow-proxies.html" rel="alternate"/><published>2023-03-28T19:39:00+11:00</published><updated>2023-03-28T19:39:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-03-28:/conda-and-slow-proxies.html</id><summary type="html">&lt;p&gt;The default &lt;code&gt;conda&lt;/code&gt; connect timeout is 9.15 seconds (no idea why this is, seems to have been the case from day one). If the proxy is slow, e.g. it is in another country or AWS region, this timeout can be triggered and &lt;code&gt;conda&lt;/code&gt; will prematurely close the connection …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The default &lt;code&gt;conda&lt;/code&gt; connect timeout is 9.15 seconds (no idea why this is, seems to have been the case from day one). If the proxy is slow, e.g. it is in another country or AWS region, this timeout can be triggered and &lt;code&gt;conda&lt;/code&gt; will prematurely close the connection.&lt;/p&gt;
&lt;p&gt;To diagnose this issue, attempt &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl https://repo.anaconda.com/pkgs/main/linux-64/current_repodata.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;with proxies enabled. If that works then increase the connect timeout as follows&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda config --set remote_connect_timeout_secs 30
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;conda should now be able to update and install new packages etc.&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="oss"/></entry><entry><title>Installing python package arcgis in conda on Apple Silicon</title><link href="/installing-python-package-arcgis-in-conda-on-apple-silicon.html" rel="alternate"/><published>2023-02-04T03:37:00+11:00</published><updated>2023-02-04T03:37:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-02-04:/installing-python-package-arcgis-in-conda-on-apple-silicon.html</id><summary type="html">&lt;p&gt;In order to install the &lt;a href="https://anaconda.org/Esri/arcgis"&gt;arcgis&lt;/a&gt; package in &lt;a href="https://docs.conda.io/en/main/miniconda.html"&gt;conda&lt;/a&gt;, you have to specify the architecture &lt;span style="font-family: courier;"&gt;osx-64&lt;/span&gt; otherwise the package will not be found. This works because MacOS will capable of running &lt;span style="font-family: courier;"&gt;x86_64&lt;/span&gt; code on Apple Silicon processors - that is how efficient they are!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install -c esri/osx-64 arcgis
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In order to install the &lt;a href="https://anaconda.org/Esri/arcgis"&gt;arcgis&lt;/a&gt; package in &lt;a href="https://docs.conda.io/en/main/miniconda.html"&gt;conda&lt;/a&gt;, you have to specify the architecture &lt;span style="font-family: courier;"&gt;osx-64&lt;/span&gt; otherwise the package will not be found. This works because MacOS will capable of running &lt;span style="font-family: courier;"&gt;x86_64&lt;/span&gt; code on Apple Silicon processors - that is how efficient they are!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda install -c esri/osx-64 arcgis
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In fact to make everything else work you need to add the channels with architecture specified exactly, e.g. &lt;code&gt;conda-forge/osx-64&lt;/code&gt;, &lt;code&gt;esri/osx-64&lt;/code&gt; and &lt;code&gt;defaults/osx-64&lt;/code&gt;. Otherwise packages will be installed with a mix of architectures and appears not to be able to find each other.&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="software"/><category term="osx"/></entry><entry><title>Verifying Local iOS Backups</title><link href="/verifying-local-ios-backups.html" rel="alternate"/><published>2023-01-10T14:40:00+11:00</published><updated>2023-01-10T14:40:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2023-01-10:/verifying-local-ios-backups.html</id><summary type="html">&lt;p&gt;Backups are a great idea, and &lt;em&gt;encrypted&lt;/em&gt; backups are a even better idea. When backing up iOS devices on macOS, it is possible to set an encryption key to protect local files. There is however no straightforward GUI method to verify the encryption key.&lt;/p&gt;
&lt;p&gt;Enter &lt;span style="font-family: courier;"&gt;&lt;a href="https://github.com/mvt-project/mvt"&gt;mvt&lt;/a&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda create -n mvt …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Backups are a great idea, and &lt;em&gt;encrypted&lt;/em&gt; backups are a even better idea. When backing up iOS devices on macOS, it is possible to set an encryption key to protect local files. There is however no straightforward GUI method to verify the encryption key.&lt;/p&gt;
&lt;p&gt;Enter &lt;span style="font-family: courier;"&gt;&lt;a href="https://github.com/mvt-project/mvt"&gt;mvt&lt;/a&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;conda create -n mvt python=3.10
conda activate mvt
pip install mvt
mvt-ios extract-key /path/to/backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With the right password you will see&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;[&lt;span class="nv"&gt;mvt&lt;/span&gt;.&lt;span class="nv"&gt;ios&lt;/span&gt;.&lt;span class="nv"&gt;decrypt&lt;/span&gt;]&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Derived&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;decryption&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;backup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;backup&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;:
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;12345678901234567890&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Otherwise&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;CRITICAL [mvt.ios.decrypt] Failed to decrypt backup. Did you provide the correct password? Did you
                  point to the right backup path?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"/><category term="software"/><category term="osx"/><category term="ios"/><category term="macos"/></entry><entry><title>Build Log: ATTiny13 LED Dimmer</title><link href="/build-log-attiny13-led-dimmer.html" rel="alternate"/><published>2022-12-26T02:27:00+11:00</published><updated>2022-12-26T02:27:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-12-26:/build-log-attiny13-led-dimmer.html</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Bought some cheap USB driven warm-white LEDs off eBay for lighting display cabinets. Turns out it is just normal LED strips with a simple driver in the USB plug. Wanting to unify control of multiple LED strips into a single point I build a simple PWM based LED driver …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Bought some cheap USB driven warm-white LEDs off eBay for lighting display cabinets. Turns out it is just normal LED strips with a simple driver in the USB plug. Wanting to unify control of multiple LED strips into a single point I build a simple PWM based LED driver. It is neither constant current &lt;em&gt;nor&lt;/em&gt; constant voltage - for the simple LEDs I have it is Good Enough (tm).&lt;/p&gt;
&lt;h2&gt;Build Details&lt;/h2&gt;
&lt;p&gt;Finished product first, this is the controller  mounted on the back of the bookcase where the LED strips are mounted. 5V from a wall plug PSU enters on the left and the LEDs strips are wired in parallel on the right. The single button cycles between on and 3 levels of brightness, with max brightness consuming around 800mA.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/750bb2_IMG_4477.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGiwF5vISX2mrlldMcUi80q0n8EQDq6O8-eHkF41EBDro9_LTTLZ1SByjWsMDwawAIwZn0wBJq96PPuyRM7WI7H6BUuE0ETYrAhR02sdDvanLA2zn1Dky8GH0upgfhNNkIDgUwOSRKkHgNMHwzjrPko0uSpyVWbb2svtJ7iewMbtXNFgF35l0/w320-h240/IMG_4477.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;With the lid off, the interior layout can be examined. Essentially a single strip board containing all components and socket hardware.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/533d9f_IMG_4483.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJTYLlzhvsAAlUXaKbSszJi4xdJLBUSYgtGPhllxY6PKD_-oJK7UrRMqPx6P1WM84RnWzKBzTy0kdZCJd2UpK41D7zWVHqguN8h6v3xDBlwB00sn0uOb6xy1sKT_Yd3uH3BrrTiGIATnb-P3C6xqN0WQ2lHxm2FL6vMHUPkIw8NxrGCnuApoM/s320/IMG_4483.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The strip board is very basic: decouple and smoothing capacitor on the top-right; ATTiny13 in the middle in a socket so it can be reprogrammed; BD135 NPN transistor lower middle with base resistor to turn the LEDs on and off; and some resistors detect button press. Could have used the internal pull-up resistors but the construction demanded that the button be wires on the high side.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/34b389_IMG_4479.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFg83hBjnAHiPwxLqDBZa7x4sji4NTwVd_8lS2S1t0u1_2EKQa8dsUJubyhYdS1OGURyFxNBR7ofi8MVgCMAuXdPJDcW6F6hHpSyJv6fWSBWxNrGzzdWNWkeX_ETliyE0K8NdLtnEPDX11Qq-nJBRkf3JUOxCMR20eqmEO294QDfgzVQFno1g/s320/IMG_4479.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/6434c1_IMG_4480.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz4gB8-xnUfcpEMFGZBd1uC1swY761kM8hLi6HngBrfpVoGYSNnb8sM3c-6WUyFz80QtRdU8AnmcOqFzb4sEp2pL4l4TVGAyZPyd4kpCEfG0nG4NjyUQj-sRs4Cr0gR3DBuGbPBW2iWWz9XmsRgq-WHYvDbCOdYELCs8w3WDXljbhZdamGHio/s320/IMG_4480.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;This project was an opportunity to try a new way of encapsulating projects, namely by using PCB spacer to raise the strip board to top of the enclosure and then constructing a lid to match the button's position. This worked quite well, especially here where the NPN transistor needed some room to dissipate heat.  The spacer can be seen in the following photo. Note the vents built into it which line up with the case vents.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/5c331d_IMG_4482.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg02XecUFF0FV9sxgiXhu-rjjPjE8NP5SdJkEOHjraoReErS8qKUpanWc4HipiIB_wejYMs7kCMteb66ou6hqV78PgiFSoEpYdQ6eDTP4Jg-7fkEdoU688zKpf7xRfQGiO4jOBBa9-rgjvzGnBrNiuZIoiDPjL9eY0g7kenga5KA66Xu7fYj6s/s320/IMG_4482.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The initial case design had the vents (seen below) built in to reduce printing time, turns out they are also very useful for passive cooling of the NPN transistor. &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/50b25f_IMG_4481.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhE0pMT4MGVTBI2LkYh0Q_OpOR2JfoclZAalCg1v6Pl50-4kZpueAQaw1gFNit9UERKxulWgRMe-x6wzDa5xGWGm_8fGUDj9TOhc3AIjPfqoCpKI7oAZ8ZOg1unIiljeixCBeSnr_4im2G_Y8zYkvYd8Nqdt7J2QOtMQfGSH8Ldbl0w6CZKA_Q/s320/IMG_4481.JPG" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;In addition to the vents in the case, vents were also added to the lid to aid cooling after observing that the case as a whole was warm to touch. The goal is for the whole system to operate without fail for the ~8hr period it is designed to operate for before turning itself off due to idle timeout.&lt;/p&gt;
&lt;h3&gt;Code and CAD&lt;/h3&gt;
&lt;p&gt;The ATTiny13 was programmed using AVR ISPmkII, &lt;a href="https://platformio.org/"&gt;PlatformIO&lt;/a&gt; and &lt;a href="https://github.com/MCUdude/MicroCore#"&gt;MicroCore&lt;/a&gt;. &lt;a href="https://www.freecadweb.org/"&gt;FreeCAD&lt;/a&gt; was used to design the enclosure, using the spreadsheet workflow to parameterise dimensions such as case thickness, inteference-fit-tolerance, etc. &lt;/p&gt;
&lt;p&gt;&lt;img src="data:image/png;base64,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TtUkAgQIECBAgAABAgQIECBAgAABAgSWCQhOl/nZmgABAgQIECBAgAABAgQIECBAgACBBgUEpw12qiYRIECAAAECBAgQIECAAAECBAgQILBMQHC6zM/WBAgQIECAAAECBAgQIECAAAECBAg0KCA4bbBTNYkAAQIECBAgQIAAAQIECBAgQIAAgWUCgtNlfrYmQIAAAQIECBAgQIAAAQIECBAgQKBBAcFpg52qSQQIECBAgAABAgQIECBAgAABAgQILBMQnC7zszUBAgQIECBAgAABAgQIECBAgAABAg0KCE4b7FRNIkCAAAECBAgQIECAAAECBAgQIEBgmYDgdJmfrQkQIECAAAECBAgQIECAAAECBAgQaFBAcNpgp2oSAQIECBAgQIAAAQIECBAgQIAAAQLLBASny/xsTYAAAQIECBAgQIAAAQIECBAgQIBAgwKC0wY7VZMIECBAgAABAgQIECBAgAABAgQIEFgmIDhd5mdrAgQIECBAgAABAgQIECBAgAABAgQaFBCcNtipmkSAAAECBAgQIECAAAECBAgQIECAwDIBwekyP1sTIECAAAECBAgQIECAAAECBAgQINCggOC0wU7VJAIECBAgQIAAAQIECBAgQIAAAQIElgkITpf52ZoAAQIECBAgQIAAAQIECBAgQIAAgQYFBKcNdqomESBAgAABAgQIECBAgAABAgQIECCwTEBwuszP1gQIECBAgAABAgQIECBAgAABAgQINCggOG2wUzWJAAECBAgQIECAAAECBAgQIECAAIFlAoLTZX62JkCAAAECBAgQIECAAAECBAgQIECgQQHBaYOdqkkECBAgQIAAAQIECBAgQIAAAQIECCwTEJwu87M1AQIECBAgQIAAAQIECBAgQIAAAQINCghOG+xUTSJAgAABAgQIECBAgAABAgQIECBAYJmA4HSZn60JECBAgAABAgQIECBAgAABAgQIEGhQQHDaYKdqEgECBAgQIECAAAECBAgQIECAAAECywQEp8v8bE2AAAECBAgQIECAAAECBAgQIECAQIMCgtMGO1WTCBAgQIAAAQIECBAgQIAAAQIECBBYJiA4XeZnawIECBAgQIAAAQIECBAgQIAAAQIEGhQQnDbYqZpEgAABAgQIECBAgAABAgQIECBAgMAyAcHpMj9bEyBAgAABAgQIECBAgAABAgQIECDQoIDgtMFO1SQCBAgQIECAAAECBAgQIECAAAECBJYJCE6X+dmaAAECBAgQIECAAAECBAgQIECAAIEGBQSnDXaqJhEgQIAAAQIECBAgQIAAAQIECBAgsExAcLrMz9YECBAgQIAAAQIECBAgQIAAAQIECDQoIDhtsFM1iQABAgQIECBAgAABAgQIECBAgACBZQKC02V+tiZAgAABAgQIECBAgAABAgQIECBAoEEBwWmDnapJBAgQIECAAAECBAgQIECAAAECBAgsExCcLvOzNQECBAgQIECAAAECBAgQIECAAAECDQoIThvsVE0iQIAAAQIECBAgQIAAAQIECBAgQGCZgOB0mZ+tCRAgQIAAAQIECBAgQIAAAQIECBBoUEBw2mCnahIBAgQIECBAgAABAgQIECBAgAABAssE/n+goR6dQzqfLwAAAABJRU5ErkJggg==" width="200" height="160" /&gt; &lt;img src="data:image/png;base64,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LQgQKKqFvcg2IIAAAggggAACCCCAAAIIIIAAAhUQIFBUAURmgQACCCCAAAIIIIAAAggggAACCNSCAIGiWtiLbAMCCCCAAAIIIIAAAggggAACCCBQAQECRRVAZBYIIIAAAggggAACCCCAAAIIIIBALQgQKKqFvcg2IIAAAggggAACCCCAAAIIIIAAAhUQIFBUAURmgQACCCCAAAIIIIAAAggggAACCNSCwGxTpkzJxNmQkSNHmi5dusQZlXEQQAABBBBAAAEEEEAAAQQQQAABBFIoQImiFO40VhkBBBBAAAEEEEAAAQQQQAABBBBIQoBAURKqzBMBBBBAAAEEEEAAAQQQQAABBBBIoQCBohTuNFYZAQQQQAABBBBAAAEEEEAAAQQQSEKAQFESqswTAQQQQAABBBBAAAEEEEAAAQQQSKFAyxSuM6scEmjdunXoG50IICCBSZMmmbZt24KBAAIRAuSPCBR6IfA/AfIHhwIChQXIH4VtGIJAreUPShRxTCOAAAIIIIAAAggggAACCCCAAAIIOAECRRwICCCAAAIIIIAAAggggAACCCCAAAJOgEARBwICCCCAAAIIIIAAAggggAACCCCAgBMgUMSBgAACCCCAAAIIIIAAAggggAACCCDgBAgUcSAggAACCCCAAAIIIIAAAggggAACCDgBAkUcCAgggAACCCCAAAIIIIAAAggggAACToBAEQcCAggggAACCCCAAAIIIIAAAggggIATIFDEgYAAAggggAACCCCAAAIIIIAAAggg4AQIFHEgIIAAAggggAACCCCAAAIIIIAAAgg4AQJFHAgIIIAAAggggAACCCCAAAIIIIAAAk6AQBEHAgIIIIAAAggggAACCCCAAAIIIICAEyBQxIGAAAIIIIAAAggggAACCCCAAAIIIOAECBRxICCAAAIIIIAAAggggAACCCCAAAIIOAECRRwICCCAAAIIIIAAAggggAACCCCAAAJOgEARBwICCCCAAAIIIIAAAggggAACCCCAgBMgUMSBgAACCCCAAAIIIIAAAggggAACCCDgBAgUcSAggAACCCCAAAIIIIAAAggggAACCDgBAkUcCAgggAACCCCAAAIIIIAAAggggAACTqBlUzhMnTrVXHLJJWb69Olm7rnnNhdeeGFTLJZlIIAAAggggAACCCCAAAIIIIAAAggUIZB4oGj48OGm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ZWVTK3DDDTeYGTNmmLXXXtt07do1tdvBiiMQV2DUqFHmqquuMmussYY59NBD404WjPfyyy+bt99+28wzzzxm3333DfrH7SDPxZVivLgC9XhM1eM2xz0eGO9vgVmzZrnf+7Fjx5ojjjjCdOjQ4e+BdCGAQCyBUn9vk8p/pa5PrI1lJARSINCkgaKZM2ea2Wef3f2lwIZVrKBA//79zW+//WaOOeYYAkUVdGVW1Suw9957m7feesut4Kqrrmq6d+9e1Mree++97sZjwQUXLClQRJ4ripuRYwjU4zFVj9sc41BglByBJ554whx55JGu7wcffGCGDx+eMwZfEUCgMYFSf2+Tyn+lrk9j28lwBNIikHigaMyYMebhhx82r732mrtpatmypStV0qVLF7P//vubRRZZJC1WrCcCCCAQW2C22WYLxg13Bz3L6Pjiiy/MNddc4+aw++67m06dOpUxNyZFoD4Fbr31VjNu3Diz2GKLmaOOOqo+EdjqigiEf+PD3RWZeRPOhHNLE2LX2aKSPLbCeS7cXWfEbC4CFRdINFD0wgsvmD322MP8/PPPWSuuJy36UwDp/vvvN8sss0zWcL4ggAACaRfQTaiCOauvvrrZaKONKro548ePN+eff76bZ8eOHQkUVVSXmdWLwF133WWGDh1qVlxxRQJF9bLTE9rOrbfe2lxxxRXmww8/NIcffnhCS0l+tpxbkjeu1yUkeWzVSv6r12OD7a5egcQCRc8//7zZbbfdXL00qmND3euss4759ttvjYoIqoTRRx99ZLbaaivXPd9881WvEmuGAAIIFCmgAM61115b5FSMjgACCCCQNgFVq6DXVEgIIND0AuS/pjdnifUhkFig6Oabb3ZBonnnndfcc889Zv311w9EDzzwQLPffvu5gNHXX39tXnrpJbPFFlsEw+loWoGffvrJPQVbYIEFzLLLLmvmmGOOWCswffp0oycEqkRulVVWMXqtsJj066+/uuXOOeecZrnlljNzzz13MZMzLgI1IaB88NlnnxnV4bbyyisnmg9UT5heB15hhRWM6j4iIVBpAZ0P9IqBzu2LL764WXrppU2LFi2KWozOLaoUuF27dqZNmzaxplU++vzzz83vv/9u2rdv7yqBjzVhCSORj0pAY5IsgVKO8T/++MOo/iM9WF1++eVN3FdsdI2nc0wmk3HXePz2Z+0KvlS5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Zom2C5rRtgTdww+/ZaZN+9k9iJg8+Udz08375i2T80ceSYM9EgsUTZs2zWy22WZm8uTJbgXWWWcds/7665tFFlnEjB071jz66KPm559/NmeccYbJZDKmf//+Da4oAxFAAAEEEKh2gT//nGWuvupZt5p6avvY/x1hVlxxsWC1Nfzgg24zN930opliA0dDh75vdthhzWC4Ok45+SGjotVKV1y5u3tNwH2x/3bbratZpcOJ7knxxRcPMQcfsrFZcsmF/GA+Eah6AV3AK22//T/NoOv2Knp9yR9FkzFBHQlcO3CYCxLNN99c5v8eP8J0794h2Pr+/Tc3fXYZ6G6o9brOc899YLbbbo1gOB0IVFLgggueNKee8nBQMlqvzD/44JslL+LRR98OgkT9+m1iLr9id9Oixd/VLR9/wjZmm60vN3qtTK+mXXnVv43yQThx/ghrNN79t27j4xY1xsMPPxwEiU488URbT8OT5uSTTzaHHnqoufLKK83jjz9uixMv7Ob54IMPFjVvRkYAAQQQQKAaBfQ015eYOO307bOCRFpfXdScdPJ2waoPeeqv9/V9j48+mmzPj++6r+3bL2EOPnhjP8h9LrXUwuaY//xVXFsVMA669rms4XxBoNoFfKCobQkBTvJHte9d1q85BfQgQqVWlXbdtUtWkEj9VE+RXsnx6ekho30nnwhUXEAlq/X6vOpnfPyJI81FF/cpaxmPPvK2m14l5S68aJesIJEGrLDCYvb6aEs3jq6Pnn46+/jm/OFoivqXWKDogQcecCuy0kormQEDBuTVo9CpUyezxRZbuHHef/99e2H9dVErzsgIIIAAAghUm4DqUzn7nF7uTyUmotKii84fnBNz6xh6770vgkl0Qa8L+9x09NFbmMUWW8D1VjFqEgJpEvCB1LZtiy8JR/5I055mXZtaQDfCOjeoFGuPLTpGLr5DhyXsK51/vVDy6b2TiB4AAEAASURBVKffRo5DTwQqJaBXw95970yz9darlz3LqVOnu3ko8FSokYNwvVt+fL9gzh9eIv5nYq+e9ezZ0wWC/vnP6AtlreKii/5diWfuxXL8TWBMBBBAAAEEqkOgS5flbMMPyzW4Mk888a575Voj/WvDlbPGHTduUvB9Y1svUVRSUequXZc3//d/75hx43jIEmVEv+oUUFUDqmNLyb8yqfom9KqALvzXWOMfBSsg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zs/h7ubeSPZxc+8Blo8AAgggUC8CTR4oOvvss81tt90W+K6xxhoEigINOhBIVuCuu+4yQ4cONSuuuCKBogjq8ePHm/PPP98N6dixI4GiCKNwr6233tpcccUV5sMPPzSHH354eFCzdrMfm5U/kYXH2adxxklk5WpwpuTtGtypbBICCCCAAAJFCDRpoOjVV181eteehAACCCCQfoHZZ5/d6LUYEgII1JYAebu29idbgwACCCCAQLECTRYoUiWrqstCFSQuscQSpm3btubtt98udn0Zv4IC2heTJk0yX331ldErgG3atIk19/B0Cy64oFlmmWXMPPPME2taP9LMmTPN6NGj3StQSy65pO8dfOoVRb0i1bp1azf/YECMjp9++smVcFhggQXcds0xxxwxpjJm+vTpZsKECUbLXnrppd26FVvkXiUrtG0rrbSSibtcre9nn31mMpmMW1+ZFptKWW6xy2D8fIFK5IVSj9f8tcnvozqLxowZY1ZYYQUT97jSNun1jq+//tosvvjiLi+0aNEif+ZF9FGe+vzzz83vv/9u2rdvX/TvhV9UKdvjp+UzGQHtW/3+zDnnnGa55ZYzc889d6wFVeL3NtaCGhmp3PVI8lzW0KqXmhcqcb4Jrxd5O6xBNwIIIIAAArUjMHtTbcpFF11kPv74Y7e4Sy65JPZNS1OtXz0t588//zRnnXWWWWqppdxNYJcuXVxQpF27dqZv377m22+/jeTQBfHpp5+eNZ1u+nQDussuu5iPPvoocjq9ktKyZUu3LF2U77zzzi4A9M9//tPNa+WVVzbPP/+8m1Y3k7179zatWrUyGv6Pf/zDjXPqqafmzVvrqfnq7/rrrzfvvvuu2XjjjY0CRGr5SfNVoOm4444L6sTKm4nt8frrr5stt9zSTbfaaqu5aRXM1OtZatEpKoW3SRfse++9twuAykPzmHfeeZ3JN998EzW56/fGG2+YLbbYwi23c+fORq9hLrTQQmaTTTYxr732WuR0pS5XgQI56bUzJeVFb6dXrOo96XVYeWywwQYBhfKCN7r//vuD/uooJS9U6njNWpECX3RMb7jhhu54WmuttczCCy/sXqPz9S9FTaZtOvPMM91xrN8CtZymALKCRapXTsNzk24SFRCVk37Xc5OO/7322sv9Rqy66qouTytv77TTTi4oe/TRR7tpVWdWQynu9hS7Hxta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ffr0sXXWWafs/MgAAQTqV+Cpp56yl19+2eaff37bd999I4jx48fbqFGjbI011rC//vWv0XDeIJBWgS+//NKefvppe/HFF+2bb76xLbbYwn7/+983Wp3XXnvNnn/+eXv77bdtwQUXtKOOOsrmnXfeRtMxAIFaEmD/qKWtWf3rUu45RqFzl2LXnGupYqWYLu0CrR4o+vHHHzlpasNvzSGHHGI//PCDDR06lEBRG24HFo1ALQjccMMNPiC08MILZwWK9t57b3vppZf8Kq666qq28cYb18Lqsg51KvDhhx/67/BHH30UCXz//feNAkUjRoywE044IZpGbw466CDOebJE+FBrAuwftbZFq399yj3HKHTuUuyacy1VrBTTpV2gVQJFjzzyiJ1//vk2YcIE++yzz2yJJZbwd5o32GADO+CAA+wXv/hF2h3rpvxXXnmlvfXWW7bUUkvZ4YcfXjfrzYoiUEhg8uTJ/vim8YMGDbLevXsXmrRuhrdr1y5a1/j7aCBvEEiRwB577GEhSLTkkkvalltuaeuvv37WGjz44INRkEjfeZ3frLLKKr62XdaErfiBY1MrYtfxotg/6njjt9Gqx88r4u8rURyOm5VQJI9aEUg0UDRnzhxT1FWR23iaMWOGjRs3zv/dc889Nnr0aOvSpUt8Et5XqcCYMWP8duvevTuBoirdRhSrdQV0ATly5Ei/0F69ehEochIKKOvmwGqrrWYbbbRR624QloZABQV+/vlne+GFF3yOG264oT300EPWoUOHRkt45plnomH333+/bb755tHntnrDsamt5Otnuewf9bOtq2lNkzzH4LhZTVuasrS1QKKBouHDh0dBokUWWcT22WcfU4Dhk08+sdtvv90mTpzoT8D69+/v2/63b0/f2m39hWD5CCCAQLkCCphdeOGF5WbD/Ai0ucC7777rm2urIDvssEPeIJHGqc8MpcUWW6xRkzQ/gn8I1KAA+0cNbtQUrBLnGCnYSBSxJgQSCxS9+eabdtlll3mkX/7yl/boo4/6JmdB7cADD/S1jW6++WZ777337I477rAdd9wxjOa1FQXU14I63pxnnnmsW7duNt9881V86er8U9+Jrl27mqrukxCodoGffvrJ3njjDevUqZOtsMIKVsnqzV9//bV98MEHlslkbPnllzf18VNKmjZtmn366afWo0ePvP2fqOr09OnT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LTkjgAACCCCAAAIIIIAAAggggAACqRIgUJSqzUVhEUAAAQQQQAABBBBAAAEEEEAAgeQECBQlZ0vOCCCAAAIIIIAAAggggAACCCCAQKoECBSlanNRWAQQQAABBBBAAAEEEEAAAQQQQCA5AQJFydmSMwIIIIAAAggggAACCCCAAAIIIJAqAQJFqdpcFBYBBBBAAAEEEEAAAQQQQAABBBBIToBAUXK25IwAAggggAACCCCAAAIIIIAAAgikSqBjqkpLYRFAAIE6ELj00ktt1qxZ1qdPH1tnnXWiNX711VftiSeesHbt2tn+++9vHTp0iMaV+6bQMovJd/z48TZq1ChbY4017K9//WsxszQ7TTnlaTZzJkAAAQQQQAABBBBAAIGCAgSKCtIwAgEEEGgbgUMOOcR++OEHGzp0aFag6L777rO//e1vvlB77bWXderUqWIFLLTMYhaw995720svveQnXXXVVW3jjTcuZrYmpymnPE1mzEgEEEAAAQQQQAABBBBoUiDxQJEudm655RZ75ZVX/N+0adOsZ8+e/s7zhhtuaOuvv36TBWQkAggggEB5ApMnT7bzzz/fZzJo0CDr3bt3eRnmzK0aTiHF34dhvCKAAAIIIIAAAggggEB6BBINFOniZI899jA1S4inqVOn2rhx4+yMM86wQw891I499lhr357ukuJGvEcAAQQqJfDRRx/ZyJEjfXa9evWqeKDoyiuv9IGo1VZbzTbaaKNKFZt8EEAAAQQQQAABBBBAoA0EEgsUTZ8+3TbddFP7/PPP/WrpAkLNEX75y1/aG2+8Yffcc4998cUXds4559hnn31m5557bhusPotEAAEEEChXQMGnCy+8sNxsmB8BBBBAAAEEEEAAAQSqQCCxajz33ntvFCT605/+ZA888IAdd9xxvgPWs88+239eccUVPYGapn333XdVwFFfRZgzZ45NmTLFnn/+eR+sK3btNd97771nr732mu9wt9j5NN2nn35qL774on399ddFz6blTZo0yZ577jlTzYjZs2cXPS8TIlAtAjNnzvTffTW/TUtS02H1PfTVV19VpMjffPONTZw40dcy/fnnnyuSZzGZaLkvvPBCyce5lh53WnKc++mnn/wxVcfWTCZTzGoxDQIIIIAAAggggAACiQgkFigaO3asL/D8889vJ5xwQqOn8yy//PJ20EEH+Wl+/PFHe+ihhxJZQTJtLKBAyz/+8Q/r0qWL/epXv7K+ffvaUkstZV27drXdd9+94MWUnrikWmELLbSQde/e3VZffXX/fs0117Rrrrmm8YL+O0RBQD0Jadlll7Wll17aP8lp4YUXtm7dutlZZ51V8KJIF5Innniin0dl09Of9L1RrbThw4dba15oFlw5RtSEwMsvv2wdO3b0fzfeeGOjddLxKYy/+OKLG41XMCWMv/nmm6PxuvgfMWKE37f0nddTzBoaGvzfH//4xyiYHs1Q4TdXXXWVL9dvf/vbKGft46GsN910UzQ8/kbBY/Uht8gii9haa61liy66qG+uFvo5ik+r98ccc4zPU+uYLyk4/Ic//ME6d+5sqn2kGqY6jqy33npNHjvy5aVh2l5LLrmkX6Ze33//fT+paqeGdbvkkktMv0M6vqn8a6+9tj/O6ZiXbxuHZbX0uNPS45y+Wzq2yUPHVB1b9X6LLbawd999NxSLVwQQQAABBBBAAAEEWk0gsUDRf/7zH78SSyyxhM0333x5V0iBg5DUDI3UOgIK2qh2V27NBt09HzNmjL+YVefj8XT11Vf7C61HH300q/aXHuGti7Y999zTTjnllPgs/r36o9LFoJqlqM8qJfVHpTvmH374oR1xxBHWr18/Pzz338EHH2zHH398o8CVmjOefPLJduCBB+bOwmcEWiSgzp0XXHBBX1tN3/HcpKeNKcCqP9WWzE2aR+NU+y0EZRQ4UABAgXLtW/GkfU8BJXXmr1pySSUFPVSu3BTWJV+wVTVatt12W3v88cdNQXwl7a8TJkzwwf18TcwUEFOeOh7kptdff90233xz7xavKaPaSs8884w/dgwZMsTb5c6b77MC1spvxowZPgD0f//3f7bCCiv4ScN66fWJJ54wBeMU9Iqvp2pR7rLLLnbZZZfly95actxp6XFOTa4VEFJtSVmHvvq+/fZbX+v2N7/5DTdR8m4lBiKAAAIIIIAAAggkKZBYoEh3RpU+/vhj04l9vnTXXXdFg8P00QDeJCKgmkS6066ku/oXXXSR7zPq3//+t69NpOG6qN1tt9301idd0A0bNsx0Maigny5uFBxSLYGTTjrJ147QhKrlEwKEc+c0fzGmJmpKhx9+uA9O6QL6kUce8TUWNFz9VeXWKFNNI5VNSRfTCmC9+eabdv3110dPytN6qEN0EgLlCqgWymabbeazKRQoCsvQd1X7QjyFeXQcU605JX0/tZ8obbnllnb33Xf7JpuqzdK/f38//O2337Z//etf/n0S/xQQeeedd/z+E/I//fTT/TAN32GHHcLg6PW2224zNZM788wz/bFbtVr0XrVDlVQTtNimowrKbLXVVr4/OgVB9PCCBx980DdnU7A3ND+WgZogN5f0YARtJwWL5azjiIIp+ZJqOarMqgGmfvH0p5pPHTp08JPrvY5F8dTS446CTqUe577//ntfHgW1VLtS3ysdaxU4PO+883zQSE3mVCONhAACCCCAAAIIIIBAqwq4u7KZYv5cFf6ipgt5uQukjGu2oI4WMq45Qmb06NEZ1zzA5+ECDJl99tnHj9N41yShpLzDMnid4W7QF58++eSTyHyZZZbJuFoNjWbea6+9omnchYsf7+52ZzbZZBP/5wJKjeZxF1fRPLfffnvWeHcR58etssoqWcP1QcvXtlferklLNF7D3UWln88FszLuojUapzdffvllZtVVV/Xjf/GLX2TcxVXWeD4goO96qckFdqLvseuMP5rdBTv8cPfY94wLlPr3LkARjXe1iDKLLbaYH/63v/0tGu5qvPnv9s4775xxNUSi4Xrjao9kXG1LP88aa6yRNU4fwnKGDh2aNc49uczPo+OmCyJkjWvqg6tdE8137bXX5p00LFPreccddzSaxtUYjPKIr78mVDlVJuURT/vvv380j2tGGh/l37vgTbSurqlb1vhQnmDggkQZ18zM5+eaj2XeeuutrOn1wdXsiZbngkSZZ599ttE0++23XzSN67coGl/OcaclxzkZy0x/LngYlSO8cQF5//35/e9/X9K2DvM39dqS/aOp/BiHQC0JsH/U0tZkXSotwP5RaVHyqyWBWts/EqtRpGZlTz75pG2zzTa+I1R1aK27x+oXR31eXHHFFTbPPPPYAQccwNNy3JVCayQ1wQhJzUfU109uUkfjau6lpmmqZaGkvj10t1t/AwYMyJ3FNx0JA0MNivA5NKVQDQDVLognLT/UJlJzuJDU6aya8CipTxT11xFP6gfl1FNP9YNUsyPcyY9Pw3sEShVQzZeQHnvssfDW7r//fv9e/QttvfXW/n0Ypg9qkhVq0sXzUK0Q7TOqQbTAAgv4+cI/HftU20dJ39/wfQ/j2/K1R48ett122zUqwsCBA6Nhqk1YTFKTKiUd81Xj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eiWwemSJAAIIIIBAegRmz55j54160Be4R48Gu/OuQ61796WiFdD4A/a/ytcqmuECR+PGTbQddlgzGs8bBBBAAAEEEEAAAQTKFUikM2vVGtp///2jINHw4cPttttus4MPPtgPv/76631Nonbt2tmcOXPs+OOPL3c9mB8BBBBAAIHUC4wb97pNm/aVX4/jR2yfFSTSwA4d2tuxw/tF63nfveOj97xBAAEEEEAAAQQQQKASAonUKHrsscdsypQpvnwDBgywww47rFFZ1STtrbfe8gGjRx991N0VHUcTtEZKDEAAAQQQqCeBRRftZCed3N+v8vbb/ybvqi+xxEKmGy2ZTMa/5p2IgQgggAACCCCAAAIItFAgkRpF6sA6pK233jq8bfQaH3frrXP7Y2g0EQMQQAABBBCoE4G+fbvZMcds6//mm+8Xedf6nnte9UEijfzdhivnnYaBCCCAAAIIIIAAAgi0VCCRGkVffTW32rwK1b1794JlW2WVVaJx6viahAACCCCAAAL5BebMyditt75of9r3cj9Bnz7L23bb5a91lD8HhiKAAAIIIIAAAggg0LxAIoGi3/zmfyeur7zyivXs2TNvSV566aVoeGiqFg3gDQIIIIAAAnUucMjBY+ztt6fZd9/NsldemeT6/vvRi2y66ap2w40H8MSzOv9+sPoIIIAAAggggEASAok0PVtnnXVch5sdfHlvuukm++mnnxqVXX0rjBkzJho+a9Ys++GHH6LPvEEAAQRaKtDQ0NDSWZkPgaoSeOKJd+z//m+i6TUEiXr16mL9d1rLOneev0VlZf9oERsz1YkA+0edbGhWEwEEEECgSYFEAkWdO3e2Pn36+AU/+eSTNnjw4KwgkIJCQ4cOtVtuuSWrcN9//33WZz4ggAACLRGYOnVqS2ZjHgSqTuCAv2xixx23nR199Da2++7rWbduS9iECVPswL9eY33WOsE++eTLksvM/lEyGTPUkQD7Rx1tbFYVAQQQQKCgQCJNz7S0Sy65xPWdsJ199NFHdtddd9n9999va621lnXs2NHUH5FqD6nW0YYbbmgPP/ywf3KLAkwkBBBAAAEEEJgrMHjwRlkUP/88x04/fawNP/ZWGz9+sg3e70q7+57GTxbNmokPCCCAAAIIIIAAAgiUIJBIjSItv0uXLnb77bdb165dfXFUi+jpp5+2xx9/3AeJFltsMbvoootskUUW8eMXWmihqLmaH8A/BBBAAAEEEMgS6NixvX8iWr9+a/jhY8e+Zp999nXWNHxAAAEEEEAAAQQQQKAcgcRqFKlQyy67rK89NH78eHvsscfshRdesKWWWspWXXVVX9to8cUXt3/961++/LQJL2czMi8CCCCAQC0ITJ78heu4+kdbaKH5raFh4YKrtPEmPVxt3Vf8+IkTp9jGG/coOC0jEEAAAQQQQAABBBAoRSDRQJEK0r59e1t99dX9X27BZs6cae+++64fvO666+aO5jMCCCCAAAJ1JbD7bhe7GytvW/fuS9lbb5/qm2XnA5j00efR4Pnnnyd6zxsEEEAAAQQQQAABBMoVSKTp2ccff2wjRozwf2puViiNHDnS1CRNSX0VkRBAAAEEEKhngV12nXvT5N13p7sngz6Tl0K1jm6++QU/TkGiVVbhKX95oRiIAAIIIIAAAggg0CKBRAJFalJ23XXX2XnnnWcHHnig5Xua2cSJE2306NG+0OrPaOutt27RCjATAggggAACtSIwcODaNt98v/Crs+cel9ohB4+xJ554x7788jt7++1pdvXVT9nafU6wKVO+8NMcfPCm1rnz/LWy+qwHAggggAACCCCAQBUIJBIoWmCBBWz//ff3qzdp0iTbaqutfEfWP/74ow8ajR071j3md3ebPXu2n2bYsGE2zzxUna+C7wNFQAABBBBoQ4FFF+1kDz50VNQ/0XnnPWgb/u5UW2zRg6zHr4+xvfe6zD79dKYv4dFHb2OnjhzQhqVl0QgggAACCCCAAAK1KJBYH0UKFD355JO+E2vVHurXr5/3a9eunWUymchS0w0aNCj6zBsEEEAAAQTqWWC99Va0F14cYUMOv979jr5jamoW0gILzGNrrtnVDvjLJu63k779gguvCCCAAAIIIIAAApUTSCxQtOCCC7o+FG620047zc4//3z74YcffKlDkGjppZe2IUOG2L777lu5tSEnBBBAAAEEakBATzy7/oYD/Jp89tnX9sYbU23hhee3Xr26WIcOiVQGrgE1VgEBBBBAAAEEEECgEgKJBYpUOD3x7Oijj7ajjjrK3nzzTXvttdfcCW4H69atm6222mo277zzVmIdyAMBBBBAAIGaFVhyyYVMfyQEEEAAAQQQQAABBFpDINFAUVgBBYd69uzp/8IwXhFAAAEEEEAAAQQQQAABBBBAAAEEqkuA+uvVtT0oDQIIIIAAAggggAACCCCAAAIIINBmAgSK2oyeBSOAAAIIIIAAAggggAACCCCAAALVJUCgqLq2B6VBAAEEEEAAAQQQQAABBBBAAAEE2kyAQFGb0bNgBBBAAAEEEEAAAQQQQAABBBBAoLoECBRV1/agNAgggAACCCCAAAIIIIAAAggggECbCRAoajN6FowAAggggAACCCCAAAIIIIAAAghUlwCBouraHpQGAQQQQAABBBBAAAEEEEAAAQQQaDMBAkVtRs+CEUAAAQQQQAABBBBAAAEEEEAAgeoSIFBUXduD0iCAAAIIIIAAAggggAACCCCAAAJtJkCgqM3oWTACCCCAAAIIIIAAAggggAACCCBQXQIEiqpre1AaBBBAAAEEEEAAAQQQQAABBBBAoM0ECBS1GT0LRgABBBBAAAEEEEAAAQQQQAABBKpLgEBRdW0PSoMAAggggAACCCCAAAIIIIAAAgi0mQCBojajZ8EIIIAAAggggAACCCCAAAIIIIBAdQkQKKqu7UFpEEAAAQQQQAABBBBAAAEEEEAAgTYTIFDUZvQsGAEEEEAAAQQQQAABBBBAAAEEEKguAQJF1bU9KA0CCCCAAAIIIIAAAggggAACCCDQZgIdy1ny+PHjy5mdeUsU6N27d4lzMDkCCCCAAAIIIIAAAggggAACCCBQvEBZgaLiF8OUSQlMnTo1qazJF4FUC8zdN7ZK9TpQeASSEuC3IylZ8q0FAfaPWtiKrENSAuwfScmSby0I1NL+UVagiBoubf91bmhoaPtCUAIEqkxAB2n2jSrbKBSnagTYP6pmU1CQKhRg/6jCjUKRqkaA/aNqNgUFqUKBWts/6KOoCr9kFAkBBBBAAAEEEEAAAQQQQAABBBBoCwECRW2hzjIRQAABBBBAAAEEEEAAAQQQQACBKhQgUFSFG4UiIYAAAggggAACCCCAAAIIIIAAAm0hQKCoLdRZJgIIIIAAAggggAACCCCAAAIIIFCFAgSKqnCjUCQEEEAAAQQQQAABBBBAAAEEEECgLQQIFLWFOstEAAEEEEAAAQQQQAABBBBAAAEEqlCAQFEVbhSKhAACCCCAAAIIIIAAAggggAACCLSFAIGitlBnmQgggAACCCCAAAIIIIAAAggggEAVChAoqsKNQpEQQAABBBBAAAEEEEAAAQQQQACBthAgUNQW6iwTAQQQQAABBBBAAAEEEEAAAQQQqEIBAkVVuFEoEgIIIIAAAggggAACCCCAAAIIINAWAgSK2kKdZSKAAAIIIIAAAggggAACCCCAAAJVKECgqAo3CkVCAAEEEEAAAQQQQAABBBBAAAEE2kKAQFFbqLNMBBBAAAEEEEAAAQQQQAABBBBAoAoFCBRV4UahSAgggAACCCCAAAL/396dwFs17/8f/zSngchQphKZU5RKZpckcilD18w1lqEMiQjR76q/JBTXzJVZdRW6pBKSiBSSKVJSylgocf7r/c13WWefvc/Zw9nn7LP36/t4nPbaa33X8H2u/T2d9dnfAQEEEEAAAQQQqAwBAkWVoc45EUAAAQQQQAABBBBAAAEEEEAAgRwUIFCUgzeFS0IAAQQQQAABBBBAAAEEEEAAAQQqQ6BmZZyUc+a3wPTp0+2dd96x9dZbz84444ycKuzcuXPttttuszZt2livXr0q7Nr++OMPd94PP/zQLrroIttxxx0r7NycKHWB77//3l5//XWbNWuWrVy50jp37mwHHXSQVfX7ePfdd9uaNWusXbt21qFDh9Rh2KNgBar6Zz/ZGzdnzhx788037aOPPrIGDRpYv379rE6dOsnuTj4EEEAAAQQQQCAvBHI6ULR69Wr+QMvSx+yXX36xRx55xP1BrD+Kly1bZrvttpvtscce1qVLF9t7773TPvNjjz3mgiIbbLBBzgWKTjvtNHv77bdd2XbeeWc74IAD0i5nKjs+++yz1qdPH7fLvHnzbOrUqansTt4KFPj888/d5+KLL74Iz6r6okBRVb+PF154of3666926aWXEigK7y4LyQhU9c9+MmW89tpr7brrriuW9fzzz+fvkGIivEEAAQQQQACBQhCokEDRihUrbNiwYe6b+bp169rQoUMT2n766ad244032owZM2zJkiXuG72ddtrJtf7o1q1bwv3YkLzA4sWL7aijjrK33nqr2E6LFi2y5557zv7v//7P/vWvf7lvUotlyIM31apVC0sRXQ5XprnwwAMP2Pz5823TTTe1vn37ljhK9FzR5RIZWVHpAieffLL5INEmm2xihx56qHXq1MldV/TeRZf9RZf1OfD5Er1mun+i47IegUwFop/36HKmx9X/OyNHjnSHOeGEE6xVq1aZHjKt/V966aUwSKTy6csS/e2hlrEkBBBAAAEE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sGTJEmvatKkV2f2YIJBQ4JlnZtuxx4y03377PW6eE0/saA/95yyrVq1a3O2lrVSQ5x8977Rx495OmO1fNx5jl1/etcR2td6ot945JdbHW3HhhQfbLSNOiLcp4bqvl3ShfiTUYYMEslk39PnucugwmxYEUOOl9ddfzya9dJkL+sTbrnW33PKi9bvscVPAKV7adttNbey4C1zQN9720tb5+lFaHrYhUKgC/u+rQi0/5UagNIF8qx9Zb1E0depU6927ty1dutS5lhYoWrVqlfXv398effTR8B60bNmSQFGowQICCCCAQHkIvPvuly6QoyCRAkFnn72/HXDgjvbll9/aTf9voi1b9qONHj3DttlmExt0/dEpn/KIw2+xl176wO3XoUOLoAXRHrbVVhvZzDc+c62MVq5cbVf0f8pq165pfft2Lnb8pUt/DN936rSdNWhQJ3wfu7DzLlvEruI9AhkJZLtu/POM+8Ig0XbbbWp9gs9/o0b1bNzYt+2pp96yH3/8xQ7vOtxmvzsoCGiWbFl0zcCxdv31410Z69WrHbT8a2et22xl33/3s7388nx75ZWP7NNPl1mnvW6wGW9cbTvvvHlGHuyMAAIIIIBAIQpkLVC0Zs0aGzx4sI0aNcqKisputPTOO+8Ef6ifbQsWLCjE+0CZEUAAAQQqUODqq8bYL7+scWcccesJdv75fwvP/o9/dLCddrwyaAW72m66aaKde96BtvnmjcLtZS3MmfNlGCQ66qg97PEnzrNatWq43U44oaN1Dx5sux52s/388xob/fDrpQaKnnyqd9yH5bKuge0IpCuQzbqh7mKPPvqGuzR1NXtn9nVWv/66QKjqxiUXP2bDh79g33zzkw258dkSreX096S6rCkpiDTh2b62++5bu/f+n8GDJ5jKoPr7+GNv2HWDUg/0+mPxigACCCCAQKEKZGUwawV7unTpYiNHjnRBombNmlnr1q0TGt96663WtWvXMEjUrVu3hHnZgAACCCCAQCYCH3+81CZMeNcdYocdmti55xbv3rzFFhvapZcd5rarm8ydd0xJ6XQvvriuJZF2uvW2E8MgkT/Ifvttb0ccse7/RI2tEm1BpDxLl/7gstaoUd023bSh341XBLIukO26MeKWF8IyXH9D9zBI5FdedXU322ijdWML3XXXy7Zq1Wq/yb3OnLnAlixZVz/OCeptbJBImQYMOMK23HJDl3/cuHfcK/8ggAACCCCAQGoCWQkUjRkzxubMmeOupHv37qbuZzvttFPCK1PLo99++8003s5jjz1m1113XcK8bEAAAQQQQCATgTlzFoW73zC4h9WsWfK/wksuOTQI0qzv8qkrTippwWffWMuW6wat9g+ssfvv1nort0otJD7/fHmxzV9/ve5BWEEiBYtICFSUQLbrhq9Lu+22lWkMsNikAaj7X3G4W60grQa6jqYVK1aGb7feOvEYjX5bNH+4IwsIIIAAAgggUKZA1v4CrV+/vt1+++121113BbPIlP2N6AEHHBD0K3/FDj744DIvmgwIIIAAAgikKzB//pJw1wODcYniJXWH0dhCSrEPq/HyR9fdPvIkm//Rv2zaK1dEVxdb/nzBuuCQxkeKHUPFtzDafPN1rSI0jtK8eUtcdzYefIsx8qacBbJZN/74o8g++WSZu+L9998h4SDxBx301xeLsXWvdRBg9cHTsWNmxR3aYNGi72zmzM/cedq2bV7OQhwOAQQQQACBwhDISqCoQ4cONmXKFOvZs2dSijfddJM9+eSTwbe3myaVn0wIIIAAAgikK/DRn60UGjasG3ZziXcsjaGi9NlnyxLOjBZvv7LWffHFCnvkkRku2x57NAu+TKlbbJelf7Yo0rhI9933irXYpp/tsvMAO+Tgm2zTTS6yPXa/1gZc+XS5XlOxC+BNwQpks27oc69WQkrNmiduDeTrnfLN//CvoK7eq1uoZvpTGj9+tvU8/k4XyFXLPHVTmzhxrnXscL2bDU0tBa8eeKTLyz8IIIAAAgggkJpAVgaz3meffVK6ipNPPjml/GRGAAEEEEAgXQHfSiH6QBrvWM2ab+xWawpuzaK0445N42VLaZ2OdeY/73cDWWvHm4eX/ELFtyjSDE56GI4mPRDPnr3Q/Xz00df22OPnhS0sovlYRiAdgWzWjWhrpWbN1tWteNfYuHEDN9OfBqP21xPNN+zmnrZH0FKoz0WPBF8yvul+6tSp6QKnarWk1KrVlq5utWvX3L3nHwQQQAABBBBITSArLYpSuwRyI4AAAgggUHECnwVjCCltueVGpZ40Or6Q36fUHZLY2Ou8h8IZ0c48cz/bd9/tS+zlxyjSNOFqVfTAg2faZwuG2iefDrF77zvDjX+knZ5+epadc/aDJfZnBQLpCvjPeTbqhj+2ri1at+Jdqz9/dB+fT8GgevVq22abrRtDTOtXr15rPkik93vvvZ1ts80mWiQhgAACCCCAQBoCWWlRlMZ1sAsCCCCAAAIVIrDxxg3c9Nvff/9zqeeLbt9447LH2iv1YMHG668fH07t/be/7WwayyheWrbsJ7d6p52a2mvTB1ijRvXCbC1abGKdO+9i++93Y9Al7hv7z3+mu5nV9OBMQiBTgWzWjWgditateNfst+t6YtNllz5uw4evmz2tQYM61rHjttamzdb23XerbNasL1xruzvvnGoPPjjdXp7W32hVFCvIewQQQAABBMoWIFBUthE5EEAAAQTySGCHHZq6waFjZxuLLeIXkdnIdtihSezmlN7fcccUu2bgWLePBuR9ekxvq107/n/BY8dd4MZbUauLaJDIn1DjtFw36Gg7+aS7XHeb11//xBR4IiGQqUA260a0DpVW9zSOke9+Gd1HZRs9ekYYJFJwaMzY8635n11Efdkfemi6nXvOg/bLL2vsqL/fau+9f0PceuTz84oAAggggAACJQXoelbShDUIINEBK24AADC3SURBVIAAAnks4B8+9TCqLiuJ0uefr3Cb1MVlgw3WS5StzPWPPz7TLjj/YZdPLYKee/5iW3/9xMdTSyK1gmjSZIOEx95vv7+6rL36yscJ87EBgVQEslk3WrbcLJzpbGEwsHWipEGvNRaX0vZBUDeaHhn9unurgapfnHRpiSCRNp5ySicbdP3RLt9XX30fTK7yoVvmHwQQQAABBBBIXoBAUfJW5EQAAQQQyAOB7f9sHaSH0Q9jZlWKFm/evK/cW//wHN2W7PL//veenXLy3W78lK23bmwvTe5nTZsmDgD9/vu6gbM1ePbPP69JeJpatWqE2zTbEwmB8hDIZt1Q98ittlo3Lti8ecVnM4teu693Whdb96ZP/8Rlbd++hWnQ60Spa9fdwk2v/7lPuIIFBBBAAAEEEChTgEBRmURkQAABBBDIJ4How+eN/3o2btGef36uvfvul25burOdvf76p9aj++2ue5gGpX5p8mVW1kxrixd/Zy236+9+hg55Lu61aeUrr3wUbttq69IH5Q4zsoBAGQLZrhv++JrN7/33F8e9miE3/vW5j6171auv+7N1wYJvwlZH8Q6iQKtP1ar5JV4RQAABBBBAIFkBAkXJSpEPAQQQQCAvBNQaYZtt1k3P/cQTb9pbb31erFyaPan/5U+G647v2SFc9gtq7fPgg6/ZCy+8H/eB9b33FtsRh9/iWgWp65paEm277aZ+94SvanW0117buu333DMtHKsluoMG7f2/wRPcqmrBU/Bhh/3VeiKaj2UEUhUoj7oxZ86XNmrU5Lif3eOOb+8uSS3nruj/VInL03T3b7zxmVuv7pWxre92331rt23Jkh+Cc0wpsb9WaLbAYTdNDLe12b1ZuMwCAggggAACCCQnQKAoOSdyIYAAAgjkiYDGN7lyQDdXGnU/U9ewN99c4N4rCHPWmffb3LmL3Hs9rB544I4lSn7G6ffa6afda10OHWYPPPBase0LFiy3Qzvf5GZh0obTTtvHBaM0EG+8H99yyR/kpJM7uUWNr9J+z0E2YcK77uF35crVNnHi3ODYw8LWThqPZbvtyg5A+WPzikBpApnWjQ8++MratL7Gzu/9sO3V8YZiU9brvPq8+iCtPtcDrx7rBp1WPVQ3zYsufCS8vGuuPSpc9guX9+9q1auvayKkcb9UDxWsXbbsR5s//2t75JEZQZ253qZNW9fiTuMiHXNMO787rwgggAACCCCQpED8KVeS3JlsCCCAAAIIVEWBM87Yx16ZNt80Q5LGKerQ/nqrU6emrVnze9hCSOOpPDz6nLjFmzFjXasHbXxjxqd2+un7hPmG3PisqcWDT0NK6UKmPBdffKi1Hna8z25nn72/fRB0yxk5crJ9+eW3dmS3EW4QYD0gqyWGT//4Rwe7597T/VteESgXgUzqhm8NpAvRzGZff/2DqdulTxpb6+kx59sB+w9xwc8bbhhv/wq6f6p72Nq1f322r7n273EDtIccsouNn9DHTjrxLheIVZA2NlDrz3XAATvaY4+fa9HxvPw2XhFAAAEEEECgdAFaFJXuw1YEEEAAgTwUUJete+49w66+uptpkF0lzYDmZ1s6/PDdbPKUfqYp6uOly/odZnXr1nJdY848a/9iWXTsVFKNGsXz16hR3W67/SS7ZcQJ4UO2rssHiTTO0SWXHGoP/ecsU14SAuUpkEnd6N69re266xYusHnGGfuGn9/o9Wla+0kvXWYdOrRwq/W59kGijTdu4D7711zz9+guxZYPO6yVzXzzauvRo204OLbPoKCQuqcNHHikvfDipbbppuv7TbwigAACCCCAQAoC1ZYvX16UTP6ZM2da+/br+pYnkz82z0UXXRQ0uR9t9evXty+++CJ2c7H3ixcvttatW7t1gwYNsl69ehXbzpu/BBo3bvzXG5YQQMAJLFmyJHiAb2pFdj8iCJQpsGLFSnv77S9c650NNqhnu+yyucUOohvvIL/++psL1GS7xcLChSvcuC1BrMg6dmxhGscok/T1ki7Uj0wAC2jfdOvGTz/9ag0b1i1TavbshaYZ0NasWesGem/btnlS+0UPvHz5yuAYXwV/X9ZxQaratTNrLO/rR/QcLCOAwDoB//cVHgggUFIg3+pHhQWKSlKypjwECBSVhyLHyDcB/4uaQFG+3VnKUx4C/kGY+lEemhwj3wR8/ci3clEeBMpDwP99VR7H4hgI5JtAvtUP2qzn2yeU8iCAAAIIIIAAAggggAACCCCAAAJpChAoShOO3RBAAAEEEEAAAQQQQAABBBBAAIF8EyBQlG93lPIggAACCCCAAAIIIIAAAggggAACaQoQKEoTjt0QQAABBBBAAAEEEEAAAQQQQACBfBMgUJRvd5TyIIAAAggggAACCCCAAAIIIIAAAmkKEChKE47dEEAAAQQQQAABBBBAAAEEEEAAgXwTIFCUb3eU8iCAAAIIIIAAAggggAACCCCAAAJpChAoShOO3RBAAAEEEEAAAQQQQAABBBBAAIF8EyBQlG93lPIggAACCCCAAAIIIIAAAggggAACaQoQKEoTjt0QQAABBBBAAAEEEEAAAQQQQACBfBMgUJRvd5TyIIAAAggggAACCCCAAAIIIIAAAmkKEChKE47dEEAAAQQQQAABBBBAAAEEEEAAgXwTIFCUb3eU8iCAAAIIIIAAAggggAACCCCAAAJpChAoShOO3RBAAAEEEEAAAQQQQAABBBBAAIF8EyBQlG93lPIggAACCCCAAAIIIIAAAggggAACaQoQKEoTjt0QQAABBBBAAAEEEEAAAQQQQACBfBMgUJRvd5TyIIAAAggggAACCCCAAAIIIIAAAmkKEChKE47dEEAAAQQQQAABBBBAAAEEEEAAgXwTqJlJgebOnZvJ7uybokCrVq1S3IPsCCCAAAIIIIAAAggggAACCCCAQPICGQWKkj8NObMlsGTJkmwdmuMiUKUF1tWNLlW6DFw8AtkSoH5kS5bj5oMAf1vlw12kDNkSoH5kS5bj5oNAPtWPjAJFtHCp/I9z06ZNK/8iuAIEckxAv6SpGzl2U7icnBGgfuTMreBCclCA+pGDN4VLyhkB6kfO3AouJAcF8q1+MEZRDn7IuCQEEEAAAQQQQAABBBBAAAEEEECgMgQIFFWGOudEAAEEEEAAAQQQQAABBBBAAAEEclCAQFEO3hQuCQEEEEAAAQQQQAABBBBAAAEEEKgMAQJFlaHOORFAAAEEEEAAAQQQQAABBBBAAIEcFCBQlIM3hUtCAAEEEEAAAQQQQAABBBBAAAEEKkOAQFFlqHNOBBBAAAEEEEAAAQQQQAABBBBAIAcFCBTl4E3hkhBAAAEEEEAAAQQQQAABBBBAAIHKECBQVBnqnBMBBBBAAAEEEEAAAQQQQAABBBDIQQECRTl4U7gkBBBAAAEEEEAAAQQQQAABBBBAoDIECBRVhjrnRAABBBBAAAEEEEAAAQQQQAABBHJQgEBRDt4ULgkBBBBAAAEEEEAAAQQQQAABBBCoDAECRZWhzjkRQAABBBBAAAEEEEAAAQQQQACBHBQgUJSDN4VLQgABBBBAAAEEEEAAAQQQQAABBCpDgEBRZahzTgQQQAABBBBAAAEEEEAAAQQQQCAHBQgU5eBN4ZIQQAABBBBAAAEEEEAAAQQQQACByhAgUFQZ6pwTAQQQQAABBBBAAAEEEEAAAQQQyEEBAkU5eFO4JAQQQAABBBBAAAEEEEAAAQQQQKAyBGpWxkk5Z9UUePfdd+3VV1+1atWq2TnnnGM1atSomgXhqhHIgkAh1o/ffvvN7r77bisqKrL999/fdt1111B27ty5dtttt1mbNm2sV69e4XoWEEAAAQQQQAABBBBAILcFcjpQtGbNGqtdu3ZuCxbQ1U2cONH69+/vSnzqqada/fr1C6j0FBWB0gUKsX789NNP1rt3bwczfPjwYoGi0047zd5++223beedd7YDDjigdEC2IoAAAggggAACCCCAQE4IVEigaMWKFTZs2DBbuXKl1a1b14YOHRq38L///rs98sgjNn36dJs5c6YtXLjQtt12W+vYsaMdfvjhdsghh8Tdj5UIIIAAArkloJaHPkWX/TpeEUAAAQQQQAABBBBAIDcFsh4omjp1qvvGeenSpU4gUaBIrYfOPPNMe+6554pJffLJJ6afhx9+2AYOHGgXXnhhse28QQABBBDIPYEHHnjARo4cabvttpvrlpZ7V8gVIYAAAggggAACCCCAQDyBrAWKFPgZPHiwjRo1yo1fEe/k0XU9e/a0adOmuVVt27Z1LYi22GILmzVrlo0ePdpWrVplgwYNslq1atl5550X3ZVlBBBAAIEcE9B4RXfccUeOXRWXgwACCCCAAAIIIIAAAmUJZCVQtGDBAvvnP/9pc+bMcedv1qyZNWrUyDTYa7z0/vvvh0Girl272r333usCQsrbo0cP69atmx133HH2yy+/2JNPPkmgKB5iBus0zshHH31k66+/vjVv3jy0z+CQae+qe/z555/b6tWrbYcddrD11lsv7WOxIwLlIUD9WKe4ZMkSW7RokSmAv/nmm5cHrTvGjz/+aB9//LE7bpMmTcrtuBwIAQQQQAABBBBAAAEE0hOont5upe81ZsyYMEjUvXt3U/eznXbaKeFOL7/8crjtxhtvLBGo2GuvvezQQw91eTSTzjfffBPmZyF5AbnVrFnT/dx1110ucHfggQe6AFG7du1s++23t8aNG9vll19ums0o2fTmm2+Gx33hhRfi7vbaa6+FefR5iE3Lli0zDZC9wQYbmAa+3X333a1BgwZ2zDHHuLGqLrnkErf/pptuGrsr7xEoFwHqR3zGp59+2nbccUcXHGrfvr0L6Gy55ZZ233332R9//BF/p2DtlVde6eqs6nRs0u+Xa6+91vQlgrbr90/Tpk3dz7HHHmsa146EAAIIIIAAAggggAAClSOQlRZFKopmxBoyZIipS1lZSS1IWrRoYQoCJPqmepdddrFx48a5bmwa5HqTTTYp67BsjxHQYOH6UVLrLgVfNMB4NKn1hAYb//777+3f//53dFPC5ehx165dGzdfNI+/Bp/x119/tSOPPNLeeOMNv8q96iFUD6ka2LxTp07u2tWlkYRANgSin1HqxzphBX6PP/748PeGd1+8eLFrNdqnTx+/qsSrgkEyja2zP//8s+2zzz72zjvvlNjn66+/tqeeesp90aBzK5BEQgABBBBAAAEEEEAAgYoVyEqLog4dOtiUKVOSChKpuApMKBgwYcKEhKVXcEhJs+eoSxIpMwGNHaUg0dlnn23PP/+8qaXWLbfc4gJ2OrJaHN15552ZnSSJvYuKilxLIh8k2nvvvU2D4KornFqm6SH1yy+/tMcffzyJo5EFgfIRoH6Ym0RAgX4Fe2rUqGGXXnqp+72uKe//7//+zwX29Tsj1aTfLT5IpJai+r3/6aefujquFqhKqv/Dhw9P9dDkRwABBBBAAAEEEEAAgXIQyEqLIn1bXJ5JgQJ9y6ykGXTUJYmUucBFF13kgkP+SBp8tnPnzqbuJQoiXXzxxW4mOnVXy1bSOFZPPPGEO7zOP3HixPD+tmzZ0o4++mjXFVGz3pEQqEiBQq8f1113nX333XeOXIGhfv36hfzqGqrf8wcddJAlakUYZo5Z0CyW6vKqVqH333+/1atXz+VQq9KjjjrKdW1bvny5RbskxxyCtwgggAACCCCAAAIIIJBFgay0KCrP69VDiB7YNMixkmZSI2UuoIeym266qcSBNJaUHhCVZP7hhx+WyFOeK956663wcGppEC8IeM8997jB0MOMLCCQZQHqh5laDikpcBwNEnn6fffd1/r27evfJv16++232+TJk10LIh8k8jvXrl07bImqIHJpYyD5fXhFAAEEEEAAAQQQQACB8hXI+UDRZZddFs6IdvLJJ1vHjh3LV6BAj6aHv0QthTR4uE++i4h/X96vGghbSdeyxx57xD18nTp1rG3btnG3sRKBbAgUev1QkHj+/PmOtrTfuRo7LJOk86jb6yuvvGLjx483tRz03UwVJCJQlIku+yKAAAIIIIAAAgggkJ5ATgeK1OLlP//5jyvZfvvt5wbHTq+Y7BUroG5eiVJ0W7YDRfPmzXOXoUFrFRBKlDTrEgmBihKI1oHYc0a35Wv9UPDGDzofLW+sRatWrWJXJfX+v//9r+l3eqNGjVx3Yi1rQHt9GcCslkkRkgkBBBBAAAEEEEAAgawJ5GygSGNX3Hjjja7gmvHswQcfNHVLIJWPgAYFz4W07bbbustYtGiRaZakREmD3ZIQqCgB6sdf0qVZlLbtryMUX7rmmmvcWERqRaQZ0RQg1u+Bdu3a2cEHH1w8M+8QQAABBBBAAAEEEECgwgVyMlA0duxYu/zyyx2GWpposOOGDRtWOE4+n1AtBhKl999/P9zUpk2bcDmZhdipsP0+P/zwg18s9rrnnnu696tXr3ZdUIpt/PONWjZExzKKl4d1CJSnQKHXD7UU0kxnSu+9915C2tKc4u30008/2b/+9S+3aauttnJdzn7++Wc3w5q6ob744os2YMCAeLuyDgEEEEAAAQQQQAABBCpIIOcCRRrktFevXm5sii233NLGjRtnm222WQVxFM5pZs6cmXC2otdffz2E0OxGZSV1H/Fp8eLFfrHYq+9iVmxl8EatCHzSfVfAKDb16dPHNAsSCYGKEij0+rHeeuvZDjvs4LhnzJiRkH369OkJt8XbMGXKlLDl4CWXXOJmTqtevfh/Q2ppREIAAQQQQAABBBBAAIHKEyj+F3rlXYc7s75RPvXUU92DRJMmTVyQSN86k8pf4LPPPos7k5FmOVPXEKW6deuaZkErK22//fZWv359l02BvdikFgOa6She0gDWf/vb39ymN954w3VJ0fglCgzpofK8885LuG+847EOgfIQoH6Y+SCx6mW8GRJfffVVGz58eErc0cGp1booNumYqQafYo/BewQQQAABBBBAAAEEEMhMoGZmu5ff3mpx8o9//MNNyb7JJpu4IFHz5s3L7wQcqYSAHvJ+/fVXO/roo02tt1566SUbMWKE+Qe4oUOHJpwZLXowtQjYbbfdTC2RJk2aZGoBpADP+uuvb7Nnz7b+/fvbl19+Gd0lXFb3lqeeeso0e5I+AxMnTnQ/YYZgYaONNjJNxa0AEgmBihIo9PqhgPGzzz5r33//vV1xxRUueHvEEUe4bsAvvPCC3XzzzWHroGTvyUEHHeR+p6xdu9ZuueUW0xcCXbp0cefQMdXtTNtICCCAAAIIIIAAAgggUHkCOdGi6IsvvrBjjjnGPSyIQgEjBRgUQIj3U9qYGZVHWbXOfOaZZ5q6l9xxxx3WuXNn23nnne2CCy5wY4WoJGeccYZ7n2yp9NDnWxUp2KRZyjbffHPr2rWrzZkzx/SAmSip65oeSA877DCLHRz3gAMOsKlTp9p2222XaHfWI1DuAtQPs5YtW9pjjz3mxipS8GbIkCEuYKtxy/r162dff/21XXrppSnZK3jcu3dvt8+KFSvsrLPOMrUa1ZhI6oqmoHO3bt1SOiaZEUAAAQQQQAABBBBAoHwFcqJFkQILS5cuDUt26623hsvxFjSWTWlTNsfbh3XFBdSt5Nxzz7W+ffu6AWX9VgV7zj777HDGOb9er35wWwVzYscVad++vWkQcrUIUJDPz2C2wQYb2NVXX23aPmHCBHe42H21cptttrHnnnvOfQ40w5n21xgpanGg9Msvv7jXePu6DfyDQDkKUD/WYR566KH26KOPunr98ccfh8KqlzfccIN179497Jbmfz/4TP69f/XrFVRWcEivmu3QJw1sr/8LNE7d+PHj3e+Y2MCxz8srAggggAACCCCAAAIIZE+gwgJF/mHBv0aLlOrDAMGCqF76y23btrVp06aZZiRbsGCBG5NIARtNVx0vqfVAaS0IDjnkENOPgjrz5893Xc80a52/50VFRSUOu2rVKtfiSBv08KgucPEGL581a5bbN9VZ2EqckBUIJClQleuHWgCl24VL9bVWrVqh0rHHHutafGqgegX01TVYddX/3o5Xr7XzjTfeGDfgrG1qPaSfJUuWuJZJqvc6rtJee+3FzGdOgn8QQAABBBBAAAEEEKgcgQoLFOmbYv3ES8OGDTP9kCpHQK1+yjMAoy5tyR5PLYfU9W3lypXWtGlT04DmW2yxRTEItTzQgLpKGs+EhEBFClTF+nHaaafZ6NGj02Jq3bq1axUY3VlBIQVz9FOeSXVePyQEEEAAAQQQQAABBBDIHYEKCxTlTpG5klwS0PhEGqdEAwerdYG6FHbs2NE0G5oG2tb4RG+//ba7ZLU40FhWJAQKRSDd+hGdXSxVq0z2TfVc5EcAAQQQQAABBBBAAIHcEyBQlHv3pOCuaNCgQS4odOedd7oBzePNfKZZ1Z555hlTVzYSAoUkkE79ULeuHj16pMWkWQZJCCCAAAIIIIAAAgggULgCBIoK6N43bNjQLrzwQldiDdabK6lBgwY2atQoO+mkk2zSpEn2wQcf2MKFC61x48am69SPuqf5WdVy5bq5jvwSyKf6ofGV9ENCAAEEEEAAAQQQQAABBFIVqLZ8+fKSIwzHOcrMmTPdzFVxNrGqEgUUTCEhgEBxAXVjZOyb4ia8Q8ALUD+8BK8IlBSgfpQ0YQ0CXoD64SV4RaCkQL7Vj+oli8gaBBBAAAEEEEAAAQQQQAABBBBAAIFCFCBQVIh3nTIjgAACCCCAAAIIIIAAAggggAACcQQIFMVBYRUCCCCAAAIIIIAAAggggAACCCBQiAIEigrxrlNmBBBAAAEEEEAAAQQQQAABBBBAII4AgaI4KKxCAAEEEEAAAQQQQAABBBBAAAEEClGAQFEh3nXKjAACCCCAAAIIIIAAAggggAACCMQRIFAUB4VVCCCAAAIIIIAAAggggAACCCCAQCEKECgqxLtOmRFAAAEEEEAAAQQQQAABBBBAAIE4AgSK4qCwCgEEEEAAAQQQQAABBBBAAAEEEChEAQJFhXjXKTMCCCCAAAIIIIAAAggggAACCCAQR4BAURwUViGAAAIIIIAAAggggAACCCCAAAKFKECgqBDvOmVGAAEEEEAAAQQQQAABBBBAAAEE4ggQKIqDwioEEEAAAQQQQAABBBBAAAEEEECgEAUIFBXiXafMCCCAAAIIIIAAAggggAACCCCAQByBmnHWJb1q7ty5SeclY+YCrVq1yvwgHAEBBBBAAAEEEEAAAQQQQAABBBBIIJBRoCjBMVldgQJLliypwLNxKgSqjgB1o+rcK6604gWoHxVvzhmrjgD1o+rcK6604gWoHxVvzhmrjkA+1Y+MAkW0cKn8D23Tpk0r/yK4AgRyTEC/pKkbOXZTuJycEaB+5Myt4EJyUID6kYM3hUvKGQHqR87cCi4kBwXyrX5kFCjKwfvDJSGAAAKhQJHdHy6zgAACXqCLX+AVAQQQQAABBBBAAIESAgxmXYKEFQgggAACCCCAAAIIIIAAAggggEBhChAoKsz7TqkRQAABBBBAAAEEEEAAAQQQQACBEgIEikqQsAIBBBBAAAEEEEAAAQQQQAABBBAoTAECRYV53yk1AggggAACCCCAAAIIIIAAAgggUEKAQFEJElYggAACCCCAAAIIIIAAAggggAAChSlAoKgw7zulRgABBBBAAAEEEEAAAQQQQAABBEoIECgqQcIKBBBAAAEEEEAAAQQQQAABBBBAoDAFCBQV5n2n1AgggAACCCCAAAIIIIAAAggggEAJAQJFJUhYgQACCCCAAAIIIIAAAggggAACCBSmAIGiwrzvlBoBBBBAAAEEEEAAAQQQQAABBBAoIUCgqAQJKxBAAAEEEEAAAQQQQAABBBBAAIHCFCBQVJj3nVIjgAACCCCAAAIIIIAAAggggAACJQQIFJUgYQUCCCCAAAIIIIAAAggggAACCCBQmAIEigrzvlNqBBBAAAEEEEAAAQQQQAABBBBAoIQAgaISJKxAAAEEEEAAAQQQQAABBBBAAAEEClOAQFFh3ndKjQACCCCAAAIIIIAAAggggAACCJQQIFBUgoQVCCCAAAIIIIAAAggggAACCCCAQGEK1CzMYlNqBBBAAAEEclvgrbc+t4kT59qs4PWddxbahhvWs3btmlvbdtvY8cfvGbyvn9sF4OoQQAABBBBAAAEEqqRAhQSKVqxYYcOGDbOVK1da3bp1bejQoQmxZs+ebS+++GLwR/E79t5771njxo2tdevW7ue4446z+vX5wzghHhsQQAABBPJC4JZbXrR+lz1ua9f+EZZn4cIV9u67X9q9975iw26aaGPHXWC77rpFuJ0FBBBAAAEEEEAAAQTKQyDrgaKpU6da7969benSpe56SwsU3XvvvTZgwIDgD+O1Ydm++uormzt3rj388MN23333uddmzZqF21lAAAEEEEAgnwSuGTjWrr9+vCtSvXq1rUePdta6zVb2/Xc/28svz7dXXvnIPv10mXXa6wab8cbVtvPOm+dT8SkLAggggAACCCCAQCULZC1QtGbNGhs8eLCNGjXKioqKyizm8OHDXX5lbNiwoXXr1s123HFH+/bbb4M/il+xWbNm2bx586xz58729ttv07KoTFEyIIAAAghUNQH9f3nPPdPcZTdtuoFNeLav7b771sWKMXjwBLv6qjFBK93V9vhjb9h1g44utp03CCCAAAIIIIAAAghkIpCVwawXLFhgXbp0sZEjR7ogkVoAqftYovT777/b3Xff7Ta3bNnSJk+ebLfeeqv16tXLrrrqKnvuuefspJNOctvVje3ll19OdCjWI4AAAgggUGUFZs5cYEuW/OCu/5xzDywRJNKGAQOOsC233NDlGTfuHffKPwgggAACCCCAAAIIlJdAVgJFY8aMsTlz5rhr7N69u6n72U477ZTwmhX4WbZsmdver18/22abbYrlrVGjhl188cXhukmTJoXLLCCAAAIIIJAvAitWrAyLsvXWjcPl2AW/LZo/Ng/vEUAAAQQQQAABBBBIRyBrXc806PSQIUOsZ8+eZV5Xo0aN3NhEyti1a9e4+TWodbVq1VwLJb2SEEAAAQQQyDeB1q23sho1qtvvv/9hY8fMslNP7eT+74uWc9Gi72zmzM/cqrZtm0c3sYwAAggggAACCCCAQMYCWQkUdejQwaZMmWItWrRI6gL32GMP009p6YUXXgjHOurUqVNpWdmGAAIIIIBAlRTYYosN7cILD7bhw1+w8eNnW8/j77RB1x9t22+/mf388xo3kPWZ/7zfzYZWs2Z1u3rgkVWynFw0AggggAACCCCAQO4KZCVQtM8++5Rbif/44w+bMGFC8Ifzhe6Ybdq0ceMfldsJOBACCCCAAAI5JDDs5p62R9BSqM9Fj9iTT77pfurUqWm//fa7/fHHuskhWrXa0m4e3tPatWueQ1fOpSCAAAIIIIAAAgjkg0BWAkWZwvTv3z+Y+vdT++WXX2zu3Lm2atUqd8j99tsvmA3mHmY8yxSY/RFAAAEEclZAwaB69WrbZputb34MotWr1xa73r333i4Yz2+TYut4gwACCCCAAAIIIIBAeQjkZKBoxowZ9t577xUrnwbD7tatmzVs2LDYet4ggAACCCCQTwKXXfq463qmMjVoUMc6dtzW2rTZ2r77bpXNmvWFzZ690O68c6o9+OB0e3laf1oV5dPNpywIIIAAAggggEAOCORkoOiMM84IpgdeEjSz/80WL14cDNo50+bNm2eXXXaZ3X///fbEE09YkyZNcoCPS0AAAQQQQKD8BEaPnhEGiRQcGjP2fGvefONiJ3jooel27jkPBq1u19hRf7/V3nv/BmvUqF6xPLxBAAEEEEAAAQQQQCBdgZwMFJ1yyinFyrN27Vq77bbbbPDgwfbBBx9Ynz597LHHHiuWhzcIIIAAAghUdYFHRr/uiqCBql+cdKk1btygRJFOOaWTLVv2o/W77An76qvvg8kjPrSjjy59QogSB2EFAggggAACCCCAAAIJBKonWJ9Tq2vWrGl9+/a1Qw891F3XpEmTgnEbVuTUNXIxCCCAAAIIZCowffon7hDt27eIGyTyx+/adTe/aK//uU+4ggUEEEAAAQQQQAABBDIQyIlA0VdffeUGr166dGmpRYnOpvbhhx+WmpeNCCCAAAIIVDWB6tXX/be8YME3VlS0boazeGX49NNl4epq1cJFFhBAAAEEEEAAAQQQyFggJwJF55xzjnXo0MGOOOKIUv8wXrRoUVjgunXrhsssIIAAAgggkA8Cu+++tSvGkiU/2KhRU+IW6ccff7FhN00Mt7XZvVm4zAICCCCAAAIIIIAAApkK5ESgqEePHq4cCxYssKeeeipumdTq6JlnnnHbFCTafvvt4+ZjJQIIIIAAAlVV4PL+Xa169XVNhC44/2E74/R77YUX3ndjEs2f/7U98sgMa7/n9TZt2keuiC1bbmbHHNOuqhaX60YAAQQQQAABBBDIQYGcGMz6qKOOsgEDBtjq1avtvPPOC6b/nWVat9NOO9ny5cvtrbfesmuvvda++eYbR3jWWWdZw4YNc5CTS0IAAQQQQCB9gUMO2cXGT+hjJ514l3333Sp74IHX3E+8Ix5wwI722OPnWq1aNeJtZh0CCCCAAAIIIIAAAmkJ5ESgqFGjRjZu3Dg77bTTTOMU3XPPPe4nXok045mCSiQEEEAAAQTyUeCww1rZzDevtv6XP2kzZy6wL7/8NiymgkK77rqFdevWxq66+kjT7GgkBBBAAAEEEEAAAQTKU6DCAkU1aqz7xtO/xhZizz33tMmTJ9tVV11lb7zxRjDl71dhlvXWW89at25tp59+uvluauFGFhBAAAEEEMgzgW233dSefKq3K9Xy5Stt3ryvrH79Oi5IVLt2hf3XnWeqFAcBBBBAAAEEEEAgGYEK+2tzxIgRpp/S0mabbWZ33323y7JixQr76KOPXBczdUFLFGAq7XhsQwABBBBAoKoLbLxxA9t3X8blq+r3ketHAAEEEEAAAQSqikCFBYpSBWncuLHttddeqe5GfgQQQAABBBBAAAEEEEAAAQQQQACBNAUY3CBNOHZDAAEEEEAAAQQQQAABBBBAAAEE8k2AQFG+3VHKgwACCCCAAAIIIIAAAggggAACCKQpQKAoTTh2QwABBBBAAAEEEEAAAQQQQAABBPJNgEBRvt1RyoMAAggggAACCCCAAAIIIIAAAgikKUCgKE04dkMAAQQQQAABBBBAAAEEEEAAAQTyTYBAUb7dUcqDAAIIIIAAAggggAACCCCAAAIIpClAoChNOHZDAAEEEEAAAQQQQAABBBBAAAEE8k2AQFG+3VHKgwACCCCAAAIIIIAAAggggAACCKQpQKAoTTh2QwABBBBAAAEEEEAAAQQQQAABBPJNgEBRvt1RyoMAAggggAACCCCAAAIIIIAAAgikKUCgKE04dkMAAQQQQAABBBBAAAEEEEAAAQTyTYBAUb7dUcqDAAIIIIAAAggggAACCCCAAAIIpClAoChNOHZDAAEEEEAAAQQQQAABBBBAAAEE8k2AQFG+3VHKgwACCCCAAAIIIIAAAggggAACCKQpQKAoTTh2QwABBBBAAAEEEEAAAQQQQAABBPJNgEBRvt1RyoMAAggggAACCCCAAAIIIIAAAgikKUCgKE04dkMAAQQQQAABBBBAAAEEEEAAAQTyTaBmJgWaO3duJruzb4oCrVq1SnEPsiOAAAIIIIAAAggggAACCCCAAALJC2QUKEr+NOTMlsCSJUuydWiOi0CVFlhXN7pU6TJw8QhkS4D/O7Ily3HzQYD6kQ93kTJkS4D6kS1ZjpsPAvlUPzIKFNHCpfI/zk2bNq38i+AKEMgxAf2Spm7k2E3hcnJGgPqRM7eCC8lBAepHDt4ULilnBKgfOXMruJAcFMi3+sEYRTn4IeOSEEAAAQQQQAABBBBAAAEEEEAAgcoQIFBUGeqcEwEEEEAAAQQQQAABBBBAAAEEEMhBAQJFOXhTuCQEEEAAAQQQQAABBBBAAAEEEECgMgQIFFWGOudEAAEEEEAAAQQQQAABBBBAAAEEclCAQFEO3hQuCQEEEEAAAQQQQAABBBBAAAEEEKgMAQJFlaHOORFAAAEEEEAAAQQQQAABBBBAAIEcFCBQlIM3hUtCAAEEEEAAAQQQQAABBBBAAAEEKkOAQFFlqHNOBBBAAAEEEEAAAQQQQAABBBBAIAcFCBTl4E3hkhBAAAEEEEAAAQQQQAABBBBAAIHKECBQVBnqnBMBBBBAAAEEEEAAAQQQQAABBBDIQQECRTl4U7gkBBBAAAEEEEAAAQQQQAABBBBAoDIECBRVhjrnRAABBBBAAAEEEEAAAQQQQAABBHJQgEBRDt4ULgkBBBBAAAEEEEAAAQQQQAABBBCoDAECRZWhzjkRQAABBBBAAAEEEEAAAQQQQACBHBQgUJSDN4VLQgABBBBAAAEEEEAAAQQQQAABBCpDgEBRZahzTgQQQAABBBBAAAEEEEAAAQQQQCAHBQgU5eBN4ZIQQAABBBBAAAEEEEAAAQQQQACByhAgUFQZ6pwTAQQQQAABBBBAAAEEEEAAAQQQyEEBAkU5eFO4JAQQQAABBBBAAAEEEEAAAQQQQKAyBGpWxElXrFhhw4YNs5UrV1rdunVt6NChSZ92/Pjx9uKLL4b5zzvvPNtpp53C9ywggAACCCCAAAIIIIAAAggggAACCJSPQNYDRVOnTrXevXvb0qVL3RWnEihatGiRXXDBBS7A5IvbrVs3AkUeg1cEEEAAAQQQQAABBBBAAAEEEECgHAWyFihas2aNDR482EaNGmVFRUVpXXLfvn2LBYnSOgg7IYAAAggggAACCCCAAAIIIIAAAggkJZCVMYoWLFhgXbp0sZEjR7ogUbNmzax169ZJXZDP9Oijj9qUKVPc28MOO8yv5hUBBBBAAAEEEEAAAQQQQAABBBBAIEsCWQkUjRkzxubMmeMuuXv37qbuZ6mMK/TNN9/YwIED3f577LGH67qWpfJzWAQQQAABBBBAAAEEEEAAAQQQQACBPwWy1vWsfv36NmTIEOvZs2fK2FdeeaV99913VqtWLRsxYoT99NNPKR+DHRBAAAEEEEAAAQQQQAABBBBAAAEEUhPISouiDh06uG5j6QSJJk2aZGPHjnWl6NOnT0otkVIrOrkRQAABBBBAAAEEEEAAAQQQQAABBKICWWlRtM8++0TPkfTyL7/8Yv369XP5W7ZsaRrMmoQAAggggAACCCCAAAIIIIAAAgggUDECWWlRlO6lDx061BYuXGjVqlWz4cOHW+3atdM9FPshgAACCCCAAAIIIIAAAggggAACCKQokDOBog8//NDuvPNOd/knnniidezYMcWikB0BBBBAAAEEEEAAAQQQQAABBBBAIBOBnAkUXXrppfbbb79Z48aN7ZprrsmkTOyLAAIIIIAAAggggAACCCCAAAIIIJCGQE4Eih5//HGbMWOGu/yBAwfahhtumEZR2AUBBBBAAAEEEEAAAQQQQAABBBBAIBOBrAxmncoFrVy50q699lq3yzbbbGMaCFvjFEXTV199Fb5dvHixLViwwI1ftMUWW4TrWUAAAQQQQAABBBBAAAEEEEAAAQQQyEyg0gNFCvx88803rhQKALVt27bUEqmLmlKTJk3svffeKzUvGxFAAAEEEEAAAQQQQAABBBBAAAEEkhfIia5nyV8uORFAAAEEEEAAAQQQQAABBBBAAAEEsiVQ6S2KWrRoYZMmTSq1fLNnzzbfkmjQoEHWqVMnq1OnTqn7sBEBBBBAAAEEEEAAAQQQQAABBBBAIDWBSg8U1apVy9q0aVPqVf/666/h9pYtW5aZP8zMAgIIIIAAAggggAACCCCAAAIIIIBA0gJ0PUuaiowIIIAAAggggAACCCCAAAIIIIBAfgtUWKCoRo0aTtK/psJavfpflxldTuUY5EUAAQQQQAABBBBAAAEEEEAAAQQQKF2gwrqejRgxwvSTTmrfvr0tX748nV3ZBwEEEEAAAQQQQAABBBBAAAEEEEAgSYG/muokuQPZEEAAAQQQQAABBBBAAAEEEEAAAQTyU4BAUX7eV0qFAAIIIIAAAggggAACCCCAAAIIpCxAoChlMnZAAAEEEEAAAQQQQAABBBBAAAEE8lOAQFF+3ldKhQACCCCAAAIIIIAAAggggAACCKQsQKAoZTJ2QAABBBBAAAEEEEAAAQQQQAABBPJTgEBRft5XSoUAAggggAACCCCAAAIIIIAAAgikLECgKGUydkAAAQQQQAABBBBAAAEEEEAAAQTyU4BAUX7eV0qFAAIIIIAAAggggAACCCCAAAIIpCxAoChlMnZAAAEEEEAAAQQQQAABBBBAAAEE8lOAQFF+3ldKhQACCCCAAAIIIIAAAggggAACCKQsQKAoZTJ2QAABBBBAAAEEEEAAAQQQQAABBPJTgEBRft5XSoUAAggggAACCCCAAAIIIIAAAgikLECgKGUydkAAAQQQQAABBBBAAAEEEEAAAQTyU4BAUX7eV0qFAAIIIIAAAggggAACCCCAAAIIpCxAoChlMnZAAAEEEEAAAQQQQAABBBBAAAEE8lOAQFF+3ldKhQACCCCAAAIIIIAAAggggAACCKQsQKAoZTJ2QAABBBBAAAEEEEAAAQQQQAABBPJT4P8DZM4w8AhrPygAAAAASUVORK5CYII=" width="205" height="160" /&gt;&lt;/p&gt;
&lt;h2&gt;To Improve&lt;/h2&gt;
&lt;div style="text-align: left;"&gt;

1.  Clean up the vents in the case, possibly increase their size and the thickness of the case in that area so it is less flimsy.
2.  Engrave into the case the LED and 5V labels.
3.  Screw terminals would have been easier to wire up.  

&lt;/div&gt;</content><category term="posts"/><category term="electronics diy"/><category term="electronics"/><category term="arduino"/><category term="cad"/><category term="freecad"/><category term="3dprinting"/></entry><entry><title>Exif Tag Types</title><link href="/exif-tag-types.html" rel="alternate"/><published>2022-12-20T04:37:00+11:00</published><updated>2022-12-20T04:37:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-12-20:/exif-tag-types.html</id><summary type="html">&lt;p&gt;Went on a journey trying to figure out what valid exif tag types are, in both JPEG and TIFF files. In summary:&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TYPE #&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Exif 2.32&lt;/th&gt;
&lt;th&gt;Tiff 6.0&lt;/th&gt;
&lt;th&gt;Adobe TN[1]&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;BYTE&lt;/td&gt;
&lt;td&gt;X&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;ASCII&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;SHORT&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;LONG&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5 …&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</summary><content type="html">&lt;p&gt;Went on a journey trying to figure out what valid exif tag types are, in both JPEG and TIFF files. In summary:&lt;/p&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;col style="width: 20%" /&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;TYPE #&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Exif 2.32&lt;/th&gt;
&lt;th&gt;Tiff 6.0&lt;/th&gt;
&lt;th&gt;Adobe TN[1]&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;BYTE&lt;/td&gt;
&lt;td&gt;X&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;ASCII&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;SHORT&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;LONG&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;RATIONAL&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;SBYTE&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;X&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;UNDEFINED&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;SSHORT&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;SLONG&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;SRATIONAL&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;DOUBLE&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;IFD&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;X&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The last 3 columns indicate where the tag type is specified. e.g. Type #9-SLONG, is documented in both Exif 2.32 and Tiff 6.0, whereas type #11-FLOAT is only defined in Tiff 6.0.&lt;/p&gt;
&lt;p&gt;[1] Adobe TN refers to "Adobe PageMaker® 6.0 TIFF Technical Notes".&lt;/p&gt;</content><category term="posts"/><category term="software"/></entry><entry><title>FSCK'ing Veracrypt Volumes on macOS</title><link href="/fscking-veracrypt-volumes-on-macos.html" rel="alternate"/><published>2022-12-20T04:33:00+11:00</published><updated>2022-12-20T04:33:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-12-20:/fscking-veracrypt-volumes-on-macos.html</id><summary type="html">&lt;p&gt;Due to unexpected power loss or disconnection of the underlying storage, the filesystem &lt;em&gt;inside&lt;/em&gt; Veracrypt volumes is desired to prevent future data loss.&lt;/p&gt;
&lt;p&gt;On macOS I tried using &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;diskutil verifyDisk /dev/diskXXX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This didn't  work for some reason, most likely because of some interaction with veracrypt. Same results via Disk …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Due to unexpected power loss or disconnection of the underlying storage, the filesystem &lt;em&gt;inside&lt;/em&gt; Veracrypt volumes is desired to prevent future data loss.&lt;/p&gt;
&lt;p&gt;On macOS I tried using &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;diskutil verifyDisk /dev/diskXXX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This didn't  work for some reason, most likely because of some interaction with veracrypt. Same results via Disk Utility application.&lt;/p&gt;
&lt;p&gt;The Veracrypt GUI however offers a "check filesystem" option if you right click on a mounted volume. Unfortunately, as of version 1.25.9, it doesn't work out-of-the-box on macOS: it fails to find &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/Applications/Utilities/Disk Utility.app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The cause is that from at least macOS 12, Disk Utility is located at  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/System/Applications/Utilities/Disk\ Utility.app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is a quick and dirty workaround&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  cd /Applications/Utilities
  sudo ln -s /System/Applications/Utilities/Disk\ Utility.app ./
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With the above symlink in place it is possible to perform filesystem verification and repair via the context menu items offered in the Veracrypt GUI.  &lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="macos"/></entry><entry><title>TigerVNC and Systemd</title><link href="/tigervnc-and-systemd.html" rel="alternate"/><published>2022-07-30T01:51:00+10:00</published><updated>2022-07-30T01:51:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2022-07-30:/tigervnc-and-systemd.html</id><summary type="html">&lt;p&gt;A quick &lt;code&gt;systemd&lt;/code&gt; service definition file for &lt;code&gt;tigervnc&lt;/code&gt; on Ubuntu 20.04&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;tigervnc&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;forking&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/vncserver -localhost no -depth 24 -geometry 1920x1080 -noreset&lt;/span&gt;
&lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;steve&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Key components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Type=forking&lt;/code&gt; so &lt;code&gt;systemd&lt;/code&gt; correctly identifies the real VNC process, not the perl …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;A quick &lt;code&gt;systemd&lt;/code&gt; service definition file for &lt;code&gt;tigervnc&lt;/code&gt; on Ubuntu 20.04&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;tigervnc&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;forking&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/vncserver -localhost no -depth 24 -geometry 1920x1080 -noreset&lt;/span&gt;
&lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;steve&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Key components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Type=forking&lt;/code&gt; so &lt;code&gt;systemd&lt;/code&gt; correctly identifies the real VNC process, not the perl script that runs and then exits&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-localhost no&lt;/code&gt; so connections from other computers are accepted. This is only needed if you are not using &lt;code&gt;ssh&lt;/code&gt; tunneling.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;User=steve&lt;/code&gt; so &lt;code&gt;tigervnc&lt;/code&gt; doesn't complain about &lt;code&gt;HOME&lt;/code&gt; not defined in the environment and uses my settings for auth and X session. Note that this is a strictly single-user setup.&lt;/li&gt;
&lt;/ol&gt;</content><category term="posts"/><category term="software"/><category term="linux"/><category term="oss"/></entry><entry><title>Using SubShapeBinders and Assembly4</title><link href="/using-subshapebinders-and-assembly4.html" rel="alternate"/><published>2022-07-21T16:09:00+10:00</published><updated>2022-07-21T16:09:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2022-07-21:/using-subshapebinders-and-assembly4.html</id><summary type="html">&lt;p&gt;Assembly4 and SubShapeBinders make it possible to assemble Parts, then using their position in the assembly to generate new Parts. However because new Parts depend on Parts in the assembly, if you try to add them to the assembly FreeCAD 0.19 will complain about cyclic redundancy, which makes sense …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Assembly4 and SubShapeBinders make it possible to assemble Parts, then using their position in the assembly to generate new Parts. However because new Parts depend on Parts in the assembly, if you try to add them to the assembly FreeCAD 0.19 will complain about cyclic redundancy, which makes sense.&lt;/p&gt;
&lt;p&gt;To get around this, one method is to change the Bind Mode of the SubShapeBinders to "Disabled" which copies the geometry but unbinds it from the base object.  &lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="oss"/></entry><entry><title>Kopia: Handling Directories That No Longer Exist</title><link href="/kopia-handling-directories-that-no-longer-exist.html" rel="alternate"/><published>2022-07-21T16:05:00+10:00</published><updated>2022-07-21T16:05:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2022-07-21:/kopia-handling-directories-that-no-longer-exist.html</id><summary type="html">&lt;p&gt;Scenario&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There exists a policy that snapshots directory ABC &lt;/li&gt;
&lt;li&gt;Directory ABC now no longer exists&lt;/li&gt;
&lt;li&gt;You want to keep existing snapshots&lt;/li&gt;
&lt;li&gt;You want to stop kopia from attempting to take any more snapshots&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In order to achieve (4):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set the policy to manual only&lt;/li&gt;
&lt;li&gt;Disable inheritance from parent/global policy …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;Scenario&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There exists a policy that snapshots directory ABC &lt;/li&gt;
&lt;li&gt;Directory ABC now no longer exists&lt;/li&gt;
&lt;li&gt;You want to keep existing snapshots&lt;/li&gt;
&lt;li&gt;You want to stop kopia from attempting to take any more snapshots&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In order to achieve (4):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Set the policy to manual only&lt;/li&gt;
&lt;li&gt;Disable inheritance from parent/global policy&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(2) is required as otherwise I find ABC's policy somehow inheriting the scheduling settings from the parent/global policy and thus is scheduled even though manual snapshots only is set.&lt;/p&gt;
&lt;p&gt;To carry out the above steps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;KopiaUI: &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;Edit Policy &lt;/span&gt;&lt;ul&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt; Scheduling &amp;gt; Manual Snapshots Only &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt; Other &amp;gt; Disable Parent Policy Evaluation&lt;br&gt;
 &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;&lt;code&gt;CLI: set policy --manual --inherit false&lt;/code&gt;&lt;/span&gt;  &lt;/li&gt;
&lt;/ul&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="oss"/></entry><entry><title>Adventures with Astroberry/KStars/Ekos</title><link href="/adventures-with-astroberrykstarsekos.html" rel="alternate"/><published>2022-03-05T04:53:00+11:00</published><updated>2022-03-05T04:53:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-03-05:/adventures-with-astroberrykstarsekos.html</id><summary type="html">&lt;p&gt;In astrophotography the combination of a goto mount, a camera and plate-solving is a powerful one. It allows you to do all kind of neat things, like polar-alignment without having a clear view of the south, extremely accurate goto functionality, and automated capture of multiple predefined targets.&lt;/p&gt;
&lt;p&gt;There are roughly …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In astrophotography the combination of a goto mount, a camera and plate-solving is a powerful one. It allows you to do all kind of neat things, like polar-alignment without having a clear view of the south, extremely accurate goto functionality, and automated capture of multiple predefined targets.&lt;/p&gt;
&lt;p&gt;There are roughly speaking three popular single-board-commputers (SBCs) that facilitate this: &lt;a href="https://astronomy-imaging-camera.com/product/asiair-pro"&gt;ASIAIR PRO&lt;/a&gt;, &lt;a href="https://www.stellarmate.com/"&gt;Stellarmate&lt;/a&gt; and and &lt;a href="https://www.astroberry.io/"&gt;astroberry&lt;/a&gt;, in increasing order of technical complexity and reduction in price, with astroberry being free. Both Stellarmate and astroberry use the same underlying software, namely &lt;a href="https://edu.kde.org/kstars/"&gt;kstars/ekos&lt;/a&gt; and &lt;a href="https://www.indilib.org/about/ekos.html"&gt;INDI Library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since both ASIAR and Stellarmate devices were out of stock, but Raspberry Pi 4s (rpi) aren't, I opted to try astroberry. Installation was straightforward, everything worked as advertised. To ease mounting I designed and printed an accessory collar that allows the rpi to be attached and removed easily.&lt;/p&gt;
&lt;table class="tr-caption-container" data-align="center" data-cellpadding="0" data-cellspacing="0" style="margin-left: auto; margin-right: auto;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/b0bdd5_AVvXsEiFh1LFOFeOQzGj1yVUqWUXIH10nkACYTQ2GP26j_D5EsV2edOX4Q8VdZok0OLPe9bu7J32rGMd0YordRXGeb0ZcGsSAnKpUNUFTjkjA2pVIcNNi6xNuWTkqAqQeXEAEr7pG1vFAQ_2HPIt3591zEP9cdBGSlzbfPjOJ2S4NhMfxhOolqlEM6c_s4032" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEiFh1LFOFeOQzGj1yVUqWUXIH10nkACYTQ2GP26j_D5EsV2edOX4Q8VdZok0OLPe9bu7J32rGMd0YordRXGeb0ZcGsSAnKpUNUFTjkjA2pVIcNNi6xNuWTkqAqQeXEAEr7pG1vFAQ-2HPIt3591zEP9cdBGSlzbfPjOJ2S4NhMfxhOolqlEM6c=w400-h300" data-border="0" width="400" height="300" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;Raspberry Pi 4 in custom case mounted the accessory collar.&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The first issue with astroberry, and possibly also with Stellarmate, is that control is done via a remote desktop session over VNC. This isn't a problem other than the fact we are forced to use a desktop software on mobile device with very different aspect ratios and interaction paradigms. The end result is a very janky user experience. There are also concerns that, as the rpi uses passive cooling, it will quickly be thermally throttled, further degrading user experience unless one adds a cooling fan and heatsink.&lt;/p&gt;
&lt;p&gt;So the next evolution is to run only the INDI server on the rpi and run kstars and ekos on a laptop, which provides a native desktop experience appropriate to the device and moves any heavy processing onto a more capable platform. This works, but does take away the main advantages of having a SBC, namely a small and light setup.  &lt;/p&gt;
&lt;p&gt;The next issue that arises is that of transfer time. Running kstar/ekos on a laptop means images captured by the rpi must be transferred before any additional algorithms, such as plate-solving, can run. With my Canon 800D it takes up to 15 seconds to transfer a single raw file over the built-in wireless. This is an unacceptable long amount of time.&lt;/p&gt;
&lt;p&gt;The logical step is then to do away with the rpi altogether and run everything on the laptop I am using anyway. In this case a lenovo X220 with extended batteries. This works well, with transfer times of approximately one second.  &lt;/p&gt;
&lt;p&gt;As an aside, the default ekos layout doesn't do well on a display that is only 768px high, with many UI elements in the capture tab unusable. Setting ekos to have tabs on the left as opposed to at the top resolved this issue.&lt;/p&gt;
&lt;p&gt;The current setup is thus:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Canon 800D with 200mm F/2.8L II&lt;/li&gt;
&lt;li&gt;SmartEQ Pro+&lt;/li&gt;
&lt;li&gt;Lenovo X220 with KStars/EKOS/INDI&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now if only the clouds would go away I can actually see how this performs in anger.  &lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="astronomy"/><category term="oss"/></entry><entry><title>Astrophotography Notes: ISO, Light Pollution, Histograms</title><link href="/astrophotography-notes-iso-light-pollution-histograms.html" rel="alternate"/><published>2022-02-22T14:32:00+11:00</published><updated>2022-02-22T14:32:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-02-22:/astrophotography-notes-iso-light-pollution-histograms.html</id><summary type="html">&lt;h3&gt;ISO&lt;/h3&gt;
&lt;p&gt;I, like many people, thought that lower ISO means less noise. However this isn't true, at least not for modern camera. As a first order approximation, my understanding is that the signal path looks something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Photons impact the sensor  &lt;/li&gt;
&lt;li&gt;Sensor generates electrical signal  &lt;/li&gt;
&lt;li&gt;ISO amplifier amplifies the …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;h3&gt;ISO&lt;/h3&gt;
&lt;p&gt;I, like many people, thought that lower ISO means less noise. However this isn't true, at least not for modern camera. As a first order approximation, my understanding is that the signal path looks something like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Photons impact the sensor  &lt;/li&gt;
&lt;li&gt;Sensor generates electrical signal  &lt;/li&gt;
&lt;li&gt;ISO amplifier amplifies the signal  &lt;/li&gt;
&lt;li&gt;Readout electronics converts the signal into digital numbers&lt;/li&gt;
&lt;li&gt;digital numbers recorded as a RAW file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Generally speaking there are two major source of noise:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Random noise inherent in the photons arriving at the sensor&lt;/li&gt;
&lt;li&gt;Noise generated by readout electronics and quantisation noise in the ADC&lt;ol&gt;
&lt;li&gt;aka readout-noise &lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can express the signal-to-noise ration (SNR) of the RAW image as follows:  &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: courier;"&gt;RAW_SNR = (ISO_gain * S) / (ISO_gain * N + N_readout)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Where &lt;span style="font-family: courier;"&gt;S&lt;/span&gt; and &lt;span style="font-family: courier;"&gt;N&lt;/span&gt; is the light signal and noise, and &lt;span style="font-family: courier;"&gt;N_readout&lt;/span&gt; is the readout-noise. &lt;span style="font-family: courier;"&gt;ISO_gain&lt;/span&gt; is the gain  corresponding to the ISO value, but not the ISO value itself. e.g. ISO 100 doesn't not mean gain of 100.&lt;/p&gt;
&lt;p&gt;Generally speaking &lt;span style="font-family: courier;"&gt;S &amp;gt;&amp;gt; N&lt;/span&gt;, that is the light signal itself has good SNR.   &lt;/p&gt;
&lt;p&gt;In low light situations where &lt;span style="font-family: courier;"&gt;S&lt;/span&gt; of a similar magnitude to &lt;span style="font-family: courier;"&gt;N_readout&lt;/span&gt;, if we use a low ISO such that &lt;span style="font-family: courier;"&gt;ISO_gain&lt;/span&gt; is 1, then &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: courier;"&gt;RAW_SNR ~= S / N_readout&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;as &lt;span style="font-family: courier;"&gt;N_readout &amp;gt;&amp;gt; N&lt;/span&gt;. &lt;/p&gt;
&lt;p&gt;By increasing the ISO such &lt;span style="font-family: courier;"&gt;(ISO_gain * N) &amp;gt;&amp;gt; N_readou&lt;/span&gt;t,  &lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: courier;"&gt;RAW_SNR = (ISO_gain * S) / (ISO_gain * N + N_readout) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: courier;"&gt; ~= (ISO_gain * S) / (ISO_gain * N) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: courier;"&gt;~= S / N&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;That is, we approximately recover the original SNR of the signal which is the best that can be asked for without additional processing.&lt;/p&gt;
&lt;p&gt;This bears out in practice. I took a series of images in low light with the same aperture and shutter speed, changing only the ISO. Each image was then digitally processed in darktable with exposure compensation so images are of the same brightness (i.e. 1 extra step of exposure for each reduction in ISO):&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/c95486_AVvXsEgZ6jX9jNtWJMU__yoWg2eRpM67OjPvhUX3rBScbc3sP48_qjMc2w9cNqzdFcpMGjjkmRyqJyOEnEAnd7joVDWSopzSw6OiW0R06AfG97nEvzq3tCwftJJA3N3Cfv5oB9nUUrB1HOXzeIES_x_rM7IiIbEpJ6AhOSorXVYjdIoOSz_QpkHNcFk_s1372" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgZ6jX9jNtWJMU__yoWg2eRpM67OjPvhUX3rBScbc3sP48-qjMc2w9cNqzdFcpMGjjkmRyqJyOEnEAnd7joVDWSopzSw6OiW0R06AfG97nEvzq3tCwftJJA3N3Cfv5oB9nUUrB1HOXzeIES-x_rM7IiIbEpJ6AhOSorXVYjdIoOSz_QpkHNcFk=w320-h277" data-border="0" width="320" height="277" /&gt;&lt;/a&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEhZp3Daiso92KS-64kotqV2dNCKvuFwGkpsHXH8SaJ0k195acEy2_uQP6I65T0KHinX9hgGbDKJEZFZ-xVANR1d1B5QHeyB8oP5JViQX5bDTwtr_bwjUrleJJUhvpqDX4SQbVgpltbTZhJyvrIJ9x3eRuoEBMGN7Y7BIdidqZIiYy6OntVJuGE=s1368" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEhZp3Daiso92KS-64kotqV2dNCKvuFwGkpsHXH8SaJ0k195acEy2_uQP6I65T0KHinX9hgGbDKJEZFZ-xVANR1d1B5QHeyB8oP5JViQX5bDTwtr_bwjUrleJJUhvpqDX4SQbVgpltbTZhJyvrIJ9x3eRuoEBMGN7Y7BIdidqZIiYy6OntVJuGE=w320-h277" data-border="0" width="320" height="277" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/4bae66_AVvXsEilUWd5rBRBCPjHT2vw4dKj_MbIHS5ggLVbLgvsPRfdcicEN6DFtgySAU3GEJOSV4Clap8gmlvvIqs2ZTkO5KQodStd1lWGiuYiBR6LQy26ys6gNrSS_v666moeJUs0ANy66sNBUuMS5uDmtXcIyaplgPgbRcka_1ek8b6fw9seODM3u4PD_YM_s1364" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEiUooDae8pEgzZ7t-E6SZFCnHE1nf2JvR1I0Own0-AdcoaYroT3OabWroLZmVyhDwHZTqPihU9G5dw1-ilk--KXY3fuqkaLT9VsdWtKUNzNkIwSAvtHlomMqdZTK9iTUc915qbSTFcntV6OvahCuQ4B6h-eImJ8DTh04hglyjc0p7hm1m9gnpw=w320-h277" data-border="0" width="320" height="277" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;img src="/media/fe634c_AVvXsEilUWd5rBRBCPjHT2vw4dKj_MbIHS5ggLVbLgvsPRfdcicEN6DFtgySAU3GEJOSV4Clap8gmlvvIqs2ZTkO5KQodStd1lWGiuYiBR6LQy26ys6gNrSS_v666moeJUs0ANy66sNBUuMS5uDmtXcIyaplgPgbRcka_1ek8b6fw9seODM3u4PD_YM_w320_h278" data-border="0" width="320" height="278" /&gt;

&lt;/div&gt;

&lt;p&gt;The improvement in image quality at ISO 6400 compared to ISO 400 is significant. &lt;/p&gt;
&lt;h3&gt;Light Pollution&lt;/h3&gt;
&lt;p&gt;With such high ISO, when I take pictures in my backyard in Bortle 7 skies, I get images that appear overexposed due to the high background brightness:&lt;/p&gt;
&lt;table class="tr-caption-container" data-align="center" data-cellpadding="0" data-cellspacing="0" style="margin-left: auto; margin-right: auto;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/a1afea_AVvXsEgY_keoesTUKyeWhiCsMPyb_bkLePHhczTyQXvsyl3MIXb1aT2YE0I74mnx4wXRTbht6EUhNjPzSfbu4d_Ds_0FlTJikEat33la0aZfbpMO_PF9TY6HM2FMKcC9KmmWRLrw3rDRDkZkPgo4wnIHorU0m5u_E3n_5KT0G_guWepUh2pfR7RNOZM_s6000" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEgY-keoesTUKyeWhiCsMPyb_bkLePHhczTyQXvsyl3MIXb1aT2YE0I74mnx4wXRTbht6EUhNjPzSfbu4d-Ds_0FlTJikEat33la0aZfbpMO_PF9TY6HM2FMKcC9KmmWRLrw3rDRDkZkPgo4wnIHorU0m5u_E3n-5KT0G_guWepUh2pfR7RNOZM=s320" data-border="0" width="320" height="213" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;Single exposure, high background brightness&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;table class="tr-caption-container" data-align="center" data-cellpadding="0" data-cellspacing="0" style="margin-left: auto; margin-right: auto;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/d869ac_AVvXsEjnokQDg4csoLfSFgDESmKrquMAnZUWi9FsUGgfwmYj6SkKo9u7i2MZqBql0U_BTPEE3ceY45WE3F9qYcVRUxwate7jSTu9Fh_FvX0ZnfA_5wB7HbOfak_0VohhFfN48gEwOUZ7gI1tx9h8P3mk12ywbHe7CDDKP2iJcwBccZ4iVh9EhcW2u6U_s400" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEjnokQDg4csoLfSFgDESmKrquMAnZUWi9FsUGgfwmYj6SkKo9u7i2MZqBql0U_BTPEE3ceY45WE3F9qYcVRUxwate7jSTu9Fh-FvX0ZnfA_5wB7HbOfak_0VohhFfN48gEwOUZ7gI1tx9h8P3mk12ywbHe7CDDKP2iJcwBccZ4iVh9EhcW2u6U=s320" data-border="0" width="320" height="160" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;Histogram, plenty of room.&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Previously I have viewed such images as "unusable". However upon looking at the histogram, it is clear that despite the background brightness, the majority of the signal is properly captured without clipping. Indeed, when post-processed in sirl, the final image does not suffer from the background glow:&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/9af33d_AVvXsEikFIdPOfY5pes9EXnkf8_lGljl_Ur9w1xJB90Q4Xjh4LI7eMe0lUyRV6TBePklra5mxgq3lQKADpIbLTsxUAsQNs5YjVZUy6Hf_NyrT8f9aG_gdulJ1tUtDOLYNPoTx1tjotjV24CeluUG0hejdbHJJIq7_0H_svuNuXpM_bjfg_Bw1caXjp0_s3129" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/a/AVvXsEikFIdPOfY5pes9EXnkf8_lGljl-Ur9w1xJB90Q4Xjh4LI7eMe0lUyRV6TBePklra5mxgq3lQKADpIbLTsxUAsQNs5YjVZUy6Hf_NyrT8f9aG-gdulJ1tUtDOLYNPoTx1tjotjV24CeluUG0hejdbHJJIq7_0H_svuNuXpM_bjfg_Bw1caXjp0=w640-h504" data-border="0" width="640" height="504" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;So be not afraid of using high ISO in light polluted skies - as long as the histogram is not clipping the signal is there and can be recovered.  &lt;/p&gt;</content><category term="posts"/><category term="astronomy"/></entry><entry><title>GDK/GTK Signal Handling Notes</title><link href="/gdkgtk-signal-handling-notes.html" rel="alternate"/><published>2022-02-19T04:55:00+11:00</published><updated>2022-02-19T04:55:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-02-19:/gdkgtk-signal-handling-notes.html</id><summary type="html">&lt;p&gt;I recently tried my hands at &lt;a href="https://github.com/freespace/toga/commits/sb-dev"&gt;implementing motion event support for canvas widgets&lt;/a&gt; in &lt;a href="https://beeware.org/project/projects/libraries/toga/"&gt;Toga&lt;/a&gt; on Linux, which uses GTK3 as its GUI back end. In the process I had learn to navigate GDK's event handling mechanics and documentation. This post is a summary of notes I made during the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently tried my hands at &lt;a href="https://github.com/freespace/toga/commits/sb-dev"&gt;implementing motion event support for canvas widgets&lt;/a&gt; in &lt;a href="https://beeware.org/project/projects/libraries/toga/"&gt;Toga&lt;/a&gt; on Linux, which uses GTK3 as its GUI back end. In the process I had learn to navigate GDK's event handling mechanics and documentation. This post is a summary of notes I made during the process.&lt;/p&gt;
&lt;div style="text-align: left;"&gt;

### Basics

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

GTK widgets general signals, which you can be notified of if you &lt;span style="font-family: courier;"&gt;connect()&lt;/span&gt; to the widget by specifying

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

1.  the name of the signal  
2.  callback to invoke when the event occurs

### Event Names

To find out what signals a widget emits you naturally look at the widget's documentation, e.g. for &lt;span style="font-family: courier;"&gt;[DrawingArea](https://docs.gtk.org/gtk4/class.DrawingArea.html)&lt;/span&gt;. However you will quickly realise not *all* signals are listed. The list does not include signals such as "draw" which is mentioned in [python-gtk-3](https://athenajc.gitbooks.io/python-gtk-3-api/content/gtk-group/gtkdrawingarea.html)'s documentation. The actual list of inherited signals can only be seen in the [documentation for &lt;span style="font-family: courier;"&gt;Widget&lt;/span&gt;](https://docs.gtk.org/gtk3/class.Widget.html#signals). Why the disparity? No idea.

### Event Mask

Not that widgets do not emit all possible signals, there is an [EventMask](https://docs.gtk.org/gdk3/enum.EventType.html) bitfield that determines which signals a widget will emit. It is not enough to simply &lt;span style="font-family: courier;"&gt;connect()&lt;/span&gt; to a signal - you must also enable those events you wish to receive if not enabled by default via &lt;span style="font-family: courier;"&gt;gtk_widget_add_event()&lt;/span&gt;. Note that the relationship between signal names defined and the event-mask required is not explicitly defined. It comes down to guessing the how they are related and trial and error.

&lt;/div&gt;</content><category term="posts"/><category term="code"/></entry><entry><title>Verifying GoTo Mount Settings</title><link href="/verifying-goto-mount-settings.html" rel="alternate"/><published>2022-02-09T06:16:00+11:00</published><updated>2022-02-09T06:16:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-02-09:/verifying-goto-mount-settings.html</id><summary type="html">&lt;p&gt;I recently got a iOptron SmartEQ Pro+ mount and while setting it up I was confused over the time. Should it be local time and then I set the UTC offset in minutes? What do I do with the DST setting?&lt;/p&gt;
&lt;p&gt;One way I found of checking whether my settings …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently got a iOptron SmartEQ Pro+ mount and while setting it up I was confused over the time. Should it be local time and then I set the UTC offset in minutes? What do I do with the DST setting?&lt;/p&gt;
&lt;p&gt;One way I found of checking whether my settings is correct is&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Look up the altitude and azimuth coordinates of a bright star like Sirius using a planetarium app&lt;/li&gt;
&lt;li&gt;Command the mount to slew to that star&lt;/li&gt;
&lt;li&gt;On arrival the altitude and azimuth coordinates are displayed on the handset&lt;/li&gt;
&lt;li&gt;Compare the coordinates shown on the handset vs coordinates obtained in step (1). They should match to at least the degree. If not the time and location setting is wrong.&lt;/li&gt;
&lt;li&gt;Tweak settings and repeat from (2) onwards until there is at least degree level agreement between the mount and reference altitude and azimuth coordinates.  &lt;/li&gt;
&lt;/ol&gt;</content><category term="posts"/><category term="astronomy"/></entry><entry><title>Goodbye SpiderOak</title><link href="/goodbye-spideroak.html" rel="alternate"/><published>2022-01-02T08:57:00+11:00</published><updated>2022-01-02T08:57:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2022-01-02:/goodbye-spideroak.html</id><summary type="html">&lt;p&gt;I have been using SpiderOak One since Edward Snowden recommended it in 2013, almost a decade ago. I have over 1.5T of deduplicated data spread across 6 or so devices. This year, in 2022, I will not be renewing my subscriptions.&lt;/p&gt;
&lt;p&gt;The main issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lack of updates: the last …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;I have been using SpiderOak One since Edward Snowden recommended it in 2013, almost a decade ago. I have over 1.5T of deduplicated data spread across 6 or so devices. This year, in 2022, I will not be renewing my subscriptions.&lt;/p&gt;
&lt;p&gt;The main issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lack of updates: the last update to SpiderOak One was in 2019-09. All recent updates have been for CrossClave. It is evident that One is no longer a priority.&lt;/li&gt;
&lt;li&gt;Lack of speed: since day one (ha!) One has always been slower than competitors like Dropbox. In the beginning it wasn't so bad and one must makes some tradeoffs for the security offered. However in recent years this has not improved and setting up a new device takes days if it ever completes the initial synchronisation. Once setup the application is bloated, slow, generates massive amounts of local metadata.  &lt;/li&gt;
&lt;li&gt;Lack of control: One installations will randomly stall on sync or update because _another_ device has  gone bad. This is not a great situations when I have devices spread across the city.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To replace SpiderOak One I am currently using:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://kopia.io/" target="_blank"&gt;Kopia&lt;/a&gt; for backup with de-duplication and client-side encryption.  The target is backblaze b2.  &lt;/li&gt;
&lt;li&gt;&lt;a href="http://Sync.com"&gt;Sync.com&lt;/a&gt; for file sync. Note that Sync.com doesn't provide the same security guarantees as Kopia or SpiderOak, but I am willing to trade that for a sync solution that is fast, quick and affordable.&lt;ol&gt;
&lt;li&gt;There is no native linux client but the Sync.com client runs decently under wine and the performance on my slowest machines are acceptable.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="posts"/><category term="computer"/><category term="software"/></entry><entry><title>Quick Survey of Some Lightweight Linux Distributions</title><link href="/quick-survey-of-some-lightweight-linux-distributions.html" rel="alternate"/><published>2021-11-24T05:35:00+11:00</published><updated>2021-11-24T05:35:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2021-11-24:/quick-survey-of-some-lightweight-linux-distributions.html</id><summary type="html">&lt;p&gt;On an ASUS E203M  &lt;/p&gt;
&lt;h2&gt;Busenlabs Lithium&lt;/h2&gt;
&lt;p&gt;Installed fine but kernel (4.9?) would immediately shutdown after decrypting the root volume due to incorrect thermal readings. Was not able to disable this via &lt;span style="font-family: courier;"&gt;thermal.nocrt=1&lt;/span&gt; boot param  &lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;h2&gt;AntiX 21&lt;/h2&gt;
&lt;p&gt;Live system did not have working mouse. Did not proceed to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On an ASUS E203M  &lt;/p&gt;
&lt;h2&gt;Busenlabs Lithium&lt;/h2&gt;
&lt;p&gt;Installed fine but kernel (4.9?) would immediately shutdown after decrypting the root volume due to incorrect thermal readings. Was not able to disable this via &lt;span style="font-family: courier;"&gt;thermal.nocrt=1&lt;/span&gt; boot param  &lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;h2&gt;AntiX 21&lt;/h2&gt;
&lt;p&gt;Live system did not have working mouse. Did not proceed to installation as I didn't want to be stuck with having to fix the mouse issue.  &lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;h2&gt;bodhi linux HWE 6.0.0&lt;/h2&gt;
&lt;p&gt;Mouse works in the live system, I like the Enlightenment lineage. No GUI setting to disable tap-to-click on the touchpad, resolved via &lt;a href="https://askubuntu.com/questions/118892/how-do-i-disable-touchpad-tap-to-click" target="_blank"&gt;&lt;span style="font-family: courier;"&gt;synclient MaxTapTime=0&lt;/span&gt;&lt;/a&gt; so not a deal breaker. However despite being lightweight there was noticable GUI lag when running the installer. &lt;/p&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;h2&gt;Q4OS Gemini, Trinity&lt;/h2&gt;
&lt;p&gt;I like the idea of Trinity Desktop and they are using a decently recent kernel as well (5.10). Installed fine but wifi doesn't connect to the 5G network. Worked fine on 2.4G. Had an annoying issue where Alt-Space didn't work, giving me ISO_Next_Group. Fixed it by setting via xkb options to use "both ctrl at the same time" to switch languages which then allowed alt-space to work as intended.  &lt;/p&gt;
&lt;p&gt;Systems feels really snappy and the retro look is not bad. Sticking with this one for now.  &lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="linux"/></entry><entry><title>3D Printing at Home</title><link href="/3d-printing-at-home.html" rel="alternate"/><published>2021-11-16T02:12:00+11:00</published><updated>2021-11-16T02:12:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2021-11-16:/3d-printing-at-home.html</id><summary type="html">&lt;h2&gt;FlashForge Creator Pro&lt;/h2&gt;
&lt;p&gt;I finally got my own 3D printer, a &lt;a href="http://www.flashforge.com/creator-pro-3d-printer/" target="_blank"&gt;FlashForge Creator Pro&lt;/a&gt;, during the EOFY sale. My choices were between the Creator Pro or the Up Mini 2 ES with the build volume of the Creator Pro being the deciding factor.  &lt;/p&gt;
&lt;p&gt;Had bit of a rocky start with …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;FlashForge Creator Pro&lt;/h2&gt;
&lt;p&gt;I finally got my own 3D printer, a &lt;a href="http://www.flashforge.com/creator-pro-3d-printer/" target="_blank"&gt;FlashForge Creator Pro&lt;/a&gt;, during the EOFY sale. My choices were between the Creator Pro or the Up Mini 2 ES with the build volume of the Creator Pro being the deciding factor.  &lt;/p&gt;
&lt;p&gt;Had bit of a rocky start with bed leveling but nothing a bit of patience won't fix. It prints reliably now though I have plans for a semi-assisted bed leveling jig.  &lt;/p&gt;
&lt;h2&gt;Designs&lt;/h2&gt;
&lt;p&gt;Over the past week I have worked on and off on an &lt;a href="https://www.thingiverse.com/thing:3710082" target="_blank"&gt;iPad mini holder&lt;/a&gt; to position it above my monitor so I can use it as a status screen or as a monitor to watch twitch while I am doing menial tasks.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/6acd59_2019_06_23_18.35__25281_2529.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_QYYaadwadP31cmEODWU4StDLl_JiKs7K6CqT-Oe5rVbCewcUIsaNmx6T1UTbASdRLfGAue0-AquOBeJtuUuLtHH3d2Kehi2vNoWLp94WFqKmgEZPZNOD1QTFKh3qO9w7ya2sA/s320/2019-06-23+18.35+%25281%2529.jpg" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;I also made a &lt;a href="https://www.thingiverse.com/thing:3710023" target="_blank"&gt;small headphone hanger&lt;/a&gt; to save a bit of space.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/d62539_2019_06_24_03.03.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLnYP8Fpnbw6_W0t77lNeyDgxjhC3N5KIGor15sQB-9wgwqeoHJQ7Vm3E1_rK7j4OYKpW5uff_QonXw6AaS3GhKqsqW4ITZHXBDNXlSMvlR8oCp1Gu1MUY9lZgeIn9lWSp-LbTUw/s320/2019-06-24+03.03.jpg" data-border="0" width="240" height="320" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Both of these designs were made in Fusion360, my first with the software. Normally I use blender because that's what I comfortable with but the Fusion brings a lot to the table and I will be using it going forward. It doesn't hurt that experience and skills with Fusion will be useful in an industrial setting.  &lt;/p&gt;
&lt;p&gt;Next on the list is some replacement end-stops for a wall hanging and a keypad bruteforcer.&lt;/p&gt;</content><category term="posts"/><category term="3dprinting"/><category term="fusion360"/></entry><entry><title>The Subtle Poison of Religion</title><link href="/the-subtle-poison-of-religion.html" rel="alternate"/><published>2021-11-16T02:10:00+11:00</published><updated>2021-11-16T02:10:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2021-11-16:/the-subtle-poison-of-religion.html</id><summary type="html">&lt;p&gt;On the 12th of November 2019, Nationals MP Barnaby Joyce said on TV that:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I acknowledge that the two people who died were most likely people who voted for the Green party, so I am not going to start attacking them. That's the last thing I want to do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On the 12th of November 2019, Nationals MP Barnaby Joyce said on TV that:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I acknowledge that the two people who died were most likely people who voted for the Green party, so I am not going to start attacking them. That's the last thing I want to do.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why does the politics of the deceased matter and why would Mr. Joyce make such a speculation? I can't help but think that Mr. Joyce did it because, on some level, he thinks those people deserve it. I think this is the subtle poison of religion: that those who do not believe as I do deserve less than I do.  &lt;/p&gt;
&lt;p&gt;This idea is widespread across all variants of Christianity: you are saved if you believe in God and Jesus and the Holy Spirit but damned if you don't. You deserve salvation only if you Believe. It is this idea that motivates the Evangelicals: they must Save you by spreading their Belief so you, too, deserve salvation. It is this idea that underpins the prosperity gospel: those who Believe is deserving of wealth and therefore the harder you Believe, whether by praying harder or donating more to the Church, the more you deserve wealth. Conveniently if you are wealthy then obviously it is because you deserve it due to your faith.  &lt;/p&gt;
&lt;p&gt;Once learned and integrated into one's world view via religious instruction, this idea, that those who do not believe as I do deserve less, poisons the lens through which an individual interacts with the world. When a core part of your identify requires you to accept that, on the basis of belief alone, not everyone is equal, then it is a small step to thinking that those who hold different political beliefs deserve less then those whose beliefs align with yours. Maybe they deserve less sympathy. Maybe they deserve less government support. Maybe they deserve less compassion or concession. Whatever the case may be, on the basis of their political belief, they are Other and they are Undeserving -- and in politics this is a problem.  &lt;/p&gt;
&lt;p&gt;Some would claim that it is possible to separate one's religious beliefs from one's political actions. I reject such claims in the same way I reject any claims one can be racist and still be a fair judge. Some would claim that some people think thusly even without religion and I would agree. However some religions &lt;u&gt;requires&lt;/u&gt; such thinking. Some would say not all religions features undeserving unbelievers and claim my title is inaccurate and I would concede their point but also point out that the major religions do not fall within this category.&lt;/p&gt;</content><category term="posts"/><category term="australia"/></entry><entry><title>How *Not* to Play with Programmable LED Strips</title><link href="/how-not-to-play-with-programmable-led-strips.html" rel="alternate"/><published>2019-12-13T14:38:00+11:00</published><updated>2019-12-13T14:38:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2019-12-13:/how-not-to-play-with-programmable-led-strips.html</id><summary type="html">&lt;h2&gt;You Need That Resistor&lt;/h2&gt;
&lt;p&gt;That resistor on the data line? Yeah you need it. Otherwise you might blow an LED which renders the entire rest of the strip useless. If that happens cut out the first LED and solder the power and data lines directly to the second LED.  &lt;/p&gt;
&lt;h2&gt;You …&lt;/h2&gt;</summary><content type="html">&lt;h2&gt;You Need That Resistor&lt;/h2&gt;
&lt;p&gt;That resistor on the data line? Yeah you need it. Otherwise you might blow an LED which renders the entire rest of the strip useless. If that happens cut out the first LED and solder the power and data lines directly to the second LED.  &lt;/p&gt;
&lt;h2&gt;You Want Shorter, Thicker, Wires&lt;/h2&gt;
&lt;p&gt;Using jumper wires, of the 300-for-\$5 variety is fine for a few LEDs. If however you have 300 LED drawing around 1A then those thin wires have non-negligible voltage drop. For me this was on the order of 0.7V or more. This means even though my power supply was putting out 5V the LED strip was only seeing 4.3V, causing flickering of the LEDs.  &lt;/p&gt;
&lt;p&gt;For any piece of wire the voltage drops increases with current simply because of V=IR. Thicker wires have less resistance per unit length and therefore less voltage drop per unit length.&lt;/p&gt;</content><category term="posts"/><category term="electronics"/></entry><entry><title>T102HAAS.303 Considered Harmful For Linux</title><link href="/t102haas303-considered-harmful-for-linux.html" rel="alternate"/><published>2019-06-24T02:20:00+10:00</published><updated>2019-06-24T02:20:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2019-06-24:/t102haas303-considered-harmful-for-linux.html</id><summary type="html">&lt;h1&gt;&lt;code&gt;T102HAAS.303&lt;/code&gt; Breaks Suspend&lt;/h1&gt;
&lt;p&gt;After upgrading my Asus Transformer Mini's BIOS to &lt;code&gt;T102HAAS.303&lt;/code&gt; suspend was &lt;strong&gt;completely&lt;/strong&gt; broken. Closing the "lid" would cause some kind of suspend that cannot be disabled in software and from which Linux 4.15.0 cannot successfully resume from (actually it does resume but the …&lt;/p&gt;</summary><content type="html">&lt;h1&gt;&lt;code&gt;T102HAAS.303&lt;/code&gt; Breaks Suspend&lt;/h1&gt;
&lt;p&gt;After upgrading my Asus Transformer Mini's BIOS to &lt;code&gt;T102HAAS.303&lt;/code&gt; suspend was &lt;strong&gt;completely&lt;/strong&gt; broken. Closing the "lid" would cause some kind of suspend that cannot be disabled in software and from which Linux 4.15.0 cannot successfully resume from (actually it does resume but the display will stay blank).  &lt;/p&gt;
&lt;p&gt;This behaviour cannot be disabled in software by editing &lt;code&gt;logind.conf&lt;/code&gt; or &lt;code&gt;acpi-support&lt;/code&gt; or any of the solutions found on the web about disabling lid action. Messing about with &lt;code&gt;acpi_osi&lt;/code&gt; didn't help either.  &lt;/p&gt;
&lt;h1&gt;Downgrading from &lt;code&gt;T102HAAS.303&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;If you are reading this after upgrading to &lt;code&gt;T102HAAS.303&lt;/code&gt; you probably want to downgrade. Unfortunately the firmware that ships with the computers, version 202, cannot be found on the Asus website. You can however find the 300 firmware if you click on "View all downloads" under the BIOS section. Download this file and put it on a FAT32 formatted USB drive then:  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reboot, hold then ESC to enter Setup&lt;/li&gt;
&lt;li&gt;Find the Easy Update entry and press ENTER, starting the easy update program&lt;/li&gt;
&lt;li&gt;Navigate to your USB drive, it will be FS0 or FS1&lt;/li&gt;
&lt;li&gt;Locate the &lt;code&gt;T102HAAS.303&lt;/code&gt; file and press ENTER&lt;/li&gt;
&lt;li&gt;When the dialogue complains that the build date is too old type the word &lt;strong&gt;risky&lt;/strong&gt; on the keyboard&lt;/li&gt;
&lt;li&gt;Select Yes on the dialogue that appears after&lt;/li&gt;
&lt;li&gt;Wait for the computer to reboot&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key to this process is the word &lt;strong&gt;risky&lt;/strong&gt; which is an undocumented feature that by-passes the build date check, allowing you to downgrade. You just type this in when the error dialogue appears, there will be no text box or anything.  &lt;/p&gt;
&lt;h1&gt;Re-enabling Hibernation&lt;/h1&gt;
&lt;p&gt;Downgrading will re-enable Secure Boot, which disables hibernation on Linux. Just disable it and hibernation will work again.  &lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="linux"/></entry><entry><title>Ubuntu 18.04 on Asus Transformer Mini (T102H)</title><link href="/ubuntu-1804-on-asus-transformer-mini-t102h.html" rel="alternate"/><published>2019-06-24T02:20:00+10:00</published><updated>2019-06-24T02:20:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2019-06-24:/ubuntu-1804-on-asus-transformer-mini-t102h.html</id><summary type="html">&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Create a USB drive with a single FAT32 partition then extract the installation ISO into it using &lt;code&gt;7z&lt;/code&gt;:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ISO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usb&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that there is no space between &lt;code&gt;-o&lt;/code&gt; and the following path.  &lt;/p&gt;
&lt;p&gt;Plug in the USB drive then turn on the …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Create a USB drive with a single FAT32 partition then extract the installation ISO into it using &lt;code&gt;7z&lt;/code&gt;:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;7&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ISO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kr"&gt;to&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usb&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that there is no space between &lt;code&gt;-o&lt;/code&gt; and the following path.  &lt;/p&gt;
&lt;p&gt;Plug in the USB drive then turn on the T102H while pressing the &lt;code&gt;ESC&lt;/code&gt; key. This will allow you to enter the settings menu and allow you to boot from USB. Select installation and follow the instructions until asked to reboot.  &lt;/p&gt;
&lt;h2&gt;Xorg Setup&lt;/h2&gt;
&lt;p&gt;An immediate problem is that the display is portrait by default. Additionally the modesetting driver is used which has worse performance than the intel driver. Fix both of these issue by placing the following file in &lt;code&gt;/usr/share/X11/xorg.conf.d/99-transformer.conf&lt;/code&gt;:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Section &amp;quot;Device&amp;quot;
 Identifier &amp;quot;i915&amp;quot;
 Driver &amp;quot;intel&amp;quot;
 Option &amp;quot;TearFree&amp;quot; &amp;quot;true&amp;quot;
 Option &amp;quot;DRI&amp;quot; &amp;quot;2&amp;quot;
 Option &amp;quot;Backlight&amp;quot; &amp;quot;intel_backlight&amp;quot;
EndSection

Section &amp;quot;Screen&amp;quot;
 Identifier &amp;quot;Screen0&amp;quot;
 Monitor &amp;quot;BuiltInLCD&amp;quot;
EndSection

Section &amp;quot;Monitor&amp;quot;
 Identifier &amp;quot;BuiltInLCD&amp;quot;
 Option &amp;quot;Rotate&amp;quot; &amp;quot;right&amp;quot;
EndSection

Section &amp;quot;InputClass&amp;quot;
 Identifier &amp;quot;BuiltInTouchscreen&amp;quot;
 MatchProduct &amp;quot;ELAN22A6:00 04F3:22A6&amp;quot;
 Option &amp;quot;TransformationMatrix&amp;quot; &amp;quot;0 1 0 -1 0 1 0 0 1&amp;quot;
EndSection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This sets the display driver to &lt;code&gt;intel&lt;/code&gt;, rotates the monitor, and also transforms touchscreen inputs to match the landscape orientation.  &lt;/p&gt;
&lt;h3&gt;i915&lt;/h3&gt;
&lt;p&gt;To further improve performance place the following into &lt;code&gt;/etc/modprobe.d/i915.conf&lt;/code&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;options i915 enable_fbc=1 enable_guc=3 enable_psr=1 disable_power_well=0 semaphores=1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Backlight&lt;/h2&gt;
&lt;p&gt;Out of the box backlight doesn't work because of &lt;a href="https://bugs.freedesktop.org/show_bug.cgi?id=96571"&gt;a module loading order issue [96571]&lt;/a&gt;. The easiest fix, found in the bug report thread, is to use &lt;code&gt;dracut&lt;/code&gt; to remove the &lt;code&gt;i915&lt;/code&gt; module from &lt;code&gt;initramfs&lt;/code&gt; so it loads after the PWM modules.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo apt install dracut
sudo dracut -f --omit-drivers=&amp;quot;i915&amp;quot;
sudo update-grub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This issue may be fixed in a later release as &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1783964"&gt;the issue has been reported to Ubuntu&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;After rebooting &lt;code&gt;/sys/class/backlight/intel_backlight/&lt;/code&gt; should exist, indicating that backlight control is available.  &lt;/p&gt;
&lt;h3&gt;Keyboard Backlight Control&lt;/h3&gt;
&lt;p&gt;Unfortunately while we can now control the backlight using programs like &lt;code&gt;xbacklight&lt;/code&gt;, the screen brightness keys (fn+F5 and fn+F6) don't work. We can get around this by binding control-F5 and control-F6 to trigger &lt;code&gt;xbacklight -dec 20&lt;/code&gt; and &lt;code&gt;xbacklight -inc 20&lt;/code&gt; respectively to decrement/increment screen brightness by 20% per keyboard press.  &lt;/p&gt;
&lt;h2&gt;Airplane Mode&lt;/h2&gt;
&lt;p&gt;Similar to the backlight control buttons the airplane mode button also doesn't work. The following script uses &lt;code&gt;rfkill&lt;/code&gt; to toggle bluetooth and wifi on/off, effectively implementing airplane mode in software. I haven't found a way to disable bluetooth and wifi in hardware.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;BLUETOOTH_OFF_BY_DEFAULT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="nv"&gt;n_devices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;rfkill&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;n_blocked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;rfkill&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;blocked&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;wc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$n_devices&lt;/span&gt;&lt;span class="s2"&gt; devices, &lt;/span&gt;&lt;span class="nv"&gt;$n_blocked&lt;/span&gt;&lt;span class="s2"&gt; blocked&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$n_blocked&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$n_devices&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;rfkill&lt;span class="w"&gt; &lt;/span&gt;unblock&lt;span class="w"&gt; &lt;/span&gt;bluetooth&lt;span class="w"&gt; &lt;/span&gt;wlan

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$BLUETOOTH_OFF_BY_DEFAULT&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;rfkill&lt;span class="w"&gt; &lt;/span&gt;block&lt;span class="w"&gt; &lt;/span&gt;bluetooth
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;rfkill&lt;span class="w"&gt; &lt;/span&gt;block&lt;span class="w"&gt; &lt;/span&gt;bluetooth&lt;span class="w"&gt; &lt;/span&gt;wlan
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Power Saving&lt;/h2&gt;
&lt;p&gt;It is a good idea to install &lt;code&gt;tlp&lt;/code&gt; to improve the running time  &lt;/p&gt;
&lt;h2&gt;TODOs:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Script and keybindings to rotate the screen and touchscreen&lt;/li&gt;
&lt;li&gt;Pressure level with the pen&lt;/li&gt;
&lt;/ul&gt;</content><category term="posts"/><category term="computer"/><category term="linux"/></entry><entry><title>IPython Notebook on GPS Timing and CDMA</title><link href="/ipython-notebook-on-gps-timing-and-cdma.html" rel="alternate"/><published>2018-08-05T14:59:00+10:00</published><updated>2018-08-05T14:59:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2018-08-05:/ipython-notebook-on-gps-timing-and-cdma.html</id><summary type="html">&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[1\]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

    %matplotlib inline

    import matplotlib
    import numpy as np
    import matplotlib.pyplot as plt

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;div class="cell border-box-sizing text_cell rendered"&gt;

&lt;div class="prompt input_prompt"&gt;

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;

# GPS Timing&lt;a href="https://www.blogger.com/blogger.g?blogID=5867400#GPS-Timing" class="anchor-link"&gt;¶&lt;/a&gt;

Carrier-phase detection is suppose to yield better timing information than tracking the pseudorandom code stream. The reason for this is supposedly that the higher frequency carrier allows for more accurate measurements of the …&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[1\]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

    %matplotlib inline

    import matplotlib
    import numpy as np
    import matplotlib.pyplot as plt

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;div class="cell border-box-sizing text_cell rendered"&gt;

&lt;div class="prompt input_prompt"&gt;

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;

# GPS Timing&lt;a href="https://www.blogger.com/blogger.g?blogID=5867400#GPS-Timing" class="anchor-link"&gt;¶&lt;/a&gt;

Carrier-phase detection is suppose to yield better timing information than tracking the pseudorandom code stream. The reason for this is supposedly that the higher frequency carrier allows for more accurate measurements of the mismatch between the generated pseduorandom code stream and the broadcasted one. This increase in accuracy comes from sharper peaks in the autocorrelation function.  
Lets try this out:  


&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[2\]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

    def corr(npoints, repeat):
        A = np.random.randint(0, 2, npoints)
        A = np.repeat(A, repeat)

        xcor = np.correlate(A, A, mode='same')
        plt.figure()
        N = len(A)
        offvec = np.arange(0, N)-N/2
        print offvec.size, xcor.size
        plt.plot(offvec, xcor, 'x-')




    # generate 5 points each repeating 20 times, a slow signal    
    corr(5,20)

    # a much faster signal
    corr(100,1)

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;div class="output_wrapper"&gt;

&lt;div class="output"&gt;




&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;

&lt;div class="output_subarea output_stream output_stdout output_text"&gt;

    100 100
    100 100

&lt;/div&gt;

&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0Agg==)

&lt;/div&gt;



&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;div class="cell border-box-sizing text_cell rendered"&gt;

&lt;div class="prompt input_prompt"&gt;

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;

It is clear that if you were trying to figure out the sample delay, you are much better off with the faster signal because the it is *very* obvious when you have the timing right. With the slower signal, you can be a little wrong and still get within a few pc of the correct correlation value.  


&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div class="cell border-box-sizing text_cell rendered"&gt;

&lt;div class="prompt input_prompt"&gt;

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;

# Code Division Multiplexing&lt;a href="https://www.blogger.com/blogger.g?blogID=5867400#Code-Division-Multiplexing" class="anchor-link"&gt;¶&lt;/a&gt;

Try out CDM for myself. It is important that -1,1 is used instead of 0,1 because multiplying by 0 is always 0.  


&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[3\]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

    def gen_code(N):
        """
        Generatea a random array containing -1 and 1 of size N
        """
        out = np.random.randint(0, 2, N)
        out *= 2
        out -= 1
        return out

    def code_modulate(signal, stretch=5, carrier=None):
        signal = np.repeat(signal, stretch)
        if carrier is None:
            carrier = gen_code(len(signal))

        return np.multiply(signal, carrier), carrier

    sig_1 = gen_code(100)
    sig_2 = gen_code(100)

    out_1, c_1 = code_modulate(sig_1)

    # generate an orthogonal array by flipping every other element
    c_2 = np.array(c_1)
    c_2[::2] = -1*c_1[::2]
    out_2, _ = code_modulate(sig_2, carrier=c_2)

    out_comb = out_1 + out_2

    def plot_sig(s, title=''):
        plt.figure()
        plt.stem(s)
        plt.ylim([min(s)-0.5, max(s)+0.5])
        plt.title(title)

    plot_sig(sig_1, 'sig_1')
    plot_sig(sig_2, 'sig_2')
    plot_sig(out_comb, 'combined output')

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;div class="output_wrapper"&gt;

&lt;div class="output"&gt;




&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0A8kKScxraXZjkkSSPJblmljElSf2b9ZvBg8DPAXdPapBkHXADcAFwNnBZkjfOOK4kqUczhUFVPVpV%0Au4E0NDsX2F1V+6vqeeBmYGtTv5dffj179+6fqpa9e/dz+eXXv7j9Pffc9+LrSy65kq1br16079E+%0AmrYZH6vtui7a9reU447Pxejcjo7VdAz6mPem/Z10vPs4jm376Fr7rOdP1/76rr1vk+prez4udU1t%0Az/0utXd9L82kqmZ+AHcB50xY9wvAjpHXlwOfbOir4JnasuWq2rNnX7WxZ8++2rLlqoJnCqrgoVq/%0A/n0jr68ceb5w38f3sfA2x7drt66Ltv0t/bhXNsztYKy77753kWMw27w3b9N0vPs4jm376FL7bOdP%0A1/76rr1vzfUtfj4uT01tz/3pau/yXhp8lM/4Ob5oA7gdeGDk8eDwvz870uaufsNgsMPbts23Okjb%0Ats2PTFQVjL8efb5w38f3sfA2x7drt66Ltv0t/bhNcztYf/rpP9+qXdd5b96mqY8+juNs7doeqy7H%0AsWt/fdfet+b6pj/Plqamtuf+0r+X+giD9S2+OfzUjF8+DgCnjbw+dbiswTwA9913F7t2vY25ubnm%0AAQ4cBjaMLBl/veHYDdjAwYOHF+lj4W2quq3r4viaFu6vbbvu4zbN7WD9k09uaNWu67w3b9PURx/H%0AcbZ2zbW3q2mSrv31XXvfms+L6c+zpalpMNbi5/5SvJfu57777mR+vtqWv6g+f7R00n2D+4Ezk2xO%0AcgJwKbCzuat54GrOP//tiwYBwCmnrAOeHVky+vr6sXUAz7Jp07G7fmwfk7c5fqx267po29/Sjjs+%0AFwuPddJJz7Zq13XeJ28zPtb1E54f21/749i2j661t6tpkq799V173ybX1+58XPqajo7VfO5PX3u7%0A99KPcf75b2d+fp75+fmp9mOiWb5WAJcAjwPPAd8AvjRcfjLwhZF2FwKPAruBaxfps6a97td8DXlf%0ATX89dPI2a++ewfhcLOU9gy7Hqul493Ec2/bRtfbVcM9g9tr7Nrm+dufj6rlnMH3tK3XPIIN+Vo8k%0AtW3bPB/96Ps544zNrbfbu3c/H/nI73Hw4GE2bVrHFVe8kx077uDgwcO8+tVPUbWep59+FZs2rZvY%0A92gfTduMj9V2XRdt+1vKccfnYnRuR8dqOgZ9zHvT/k463n0cx7Z9dK191vOna3991963SfW1PR+X%0Auqa2536X2qd9LyWhqpp+qnNRqzIMVltNkrSa9REG/jkKSZJhIEkyDCRJGAaSJAwDSRKGgSQJw0CS%0AhGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkCcNAkoRhIEnCMJAkYRhIkjAMJEkYBpIkDANJEoaB%0AJAnDQJKEYSBJwjCQJGEYSJIwDCRJzBgGSd6d5GtJXkhyTkO7fUn+IslXkvzPWcaUJPVv1m8GDwI/%0AB9y9SLvDwFxV/WhVnTvjmGvGrl27VrqEVcF5OMq5OMq56NdMYVBVj1bVbiCLNM2sY61FnuwDzsNR%0AzsVRzkW/lusDuoDbk9yf5JeWaUxJUkvrF2uQ5HZg4+giBh/u/7aqbm05zvlV9Y0kr2MQCg9X1b3T%0AlytJWgqpqtk7Se4CrqqqL7doux14uqp+c8L62QuSpDWmqha7XN9o0W8GU1iwkCSvAtZV1TNJNgDv%0AAq6f1MmsOyRJmt6sP1p6SZLHgfOALyT50nD5yUm+MGy2Ebg3yVeAPwVurarbZhlXktSvXi4TSZJe%0A2lbNj3smuTDJI0keS3LNSteznJKcmuTOJH+Z5MEk/2q4/PuT3Jbk0ST/PcmJK13rckmyLsmXk+wc%0Avl6Tc5HkxCR/lOTh4fnxj9bwXFw5/CXXB5L85yQnrJW5SHJjkkNJHhhZNnHfk1yXZPfwvHlXmzFW%0ARRgkWQfcAFwAnA1cluSNK1vVsvou8K+r6mzgx4FfGe7/tcAdVfVDwJ3AdStY43L7EPDQyOu1Ohe/%0ADXyxqt4E/AjwCGtwLpJsAn4NOKeqfpjB/c7LWDtzcRODz8dRC+57kjcD7wHeBFwE/E6SRe/Froow%0AAM4FdlfV/qp6HrgZ2LrCNS2bqvpmVX11+PwZ4GHgVAZz8Olhs08Dl6xMhcsryanATwP/cWTxmpuL%0AJK8GfrKqbgKoqu9W1XdYg3Mx9D3AhiTrgVcCB1gjczH8Ufy/GVs8ad8vBm4eni/7gN0MPmMbrZYw%0AOAV4fOT1E8Nla06S04G3MLjZvrGqDsEgMIDXr1xly+q3gKsZ/D7LEWtxLs4A/k+Sm4aXzHYMfzpv%0Azc1FVR0EPgF8nUEIfKeq7mANzsWI10/Y9/HP0wO0+DxdLWEgIMn3AZ8DPjT8hjB+d/9lf7c/yT8B%0ADg2/KTV9tX3ZzwWDSyHnAJ+qqnOAZxlcGliL58VJDP4lvBnYxOAbwjbW4Fw0mGnfV0sYHABOG3l9%0A6nDZmjH86vs54DNVdctw8aEkG4frfwD41krVt4zOBy5Osgf4L8Dbk3wG+OYanIsngMer6n8NX/8x%0Ag3BYi+fFO4E9VfXtqnoB+K/AT7A25+KISft+AHjDSLtWn6erJQzuB85MsjnJCcClwM4Vrmm5/Sfg%0Aoar67ZFlO4H3D5+/D7hlfKOXm6r6jao6rar+AYPz4M6q+mfAray9uTgEPJ7krOGidwB/yRo8Lxhc%0AHjovyd8b3gx9B4MfMFhLcxGO/bY8ad93ApcOf9rqDOBMYNH/dcCq+T2DJBcy+MmJdcCNVfWxFS5p%0A2SQ5H7iHwZ8Er+HjNxgcwD9kkPL7gfdU1ZMrVedyS/I2Bn/m5OIkr2ENzkWSH2FwI/17gT3ABxjc%0ASF2Lc7GdwT8Qnge+AvxL4O+zBuYiyWeBOeC1wCFgO/B54I9YYN+TXAf8CwZz9aE2v+i7asJAkrRy%0AVstlIknSCjIMJEmGgSTJMJAkYRhIkjAMJEkYBpIkDANJEvD/AaXk5peQHjgDAAAAAElFTkSuQmCC)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAYMAAAEKCAYAAADw2zkCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz%0AAAALEgAACxIB0t1+/AAAFqdJREFUeJzt3X+w5XV93/Hna7uhVVIgcZSwEH64SPzRSQxOCQmTeitG%0AltSwJDoKXeqPtsHJmMRYwgCpdpexndFJk04czBimlBgbg41pZTE6BUYuDJkmpf4IKj9cu7sIu7im%0ANcuvOCmy7/5xDrvHu/d87/d8v9/7A+/zMXOHc77fz/fz4/0957z2fM+5l1QVkqT1bcNqT0CStPoM%0AA0mSYSBJMgwkSRgGkiQMA0kShoEEQJJrkly/2vOQVkv8PQNpGEneAvwq8BLgMeCPgGuq6tCqTkxq%0AwXcG0nCeB7wLeAHwE8D5wK+v6oyklgwDrTtJrkrySJLHk9yf5B8n2Z7koxNt3pJkb5K/SvKeJHuS%0AvKap36r6var6s6r6TlU9CvwhcN5yr0cagmGgdSXJWcA7gVdV1XHABcDe8e4at3k58CHgUuAk4Hhg%0AU4fh/hHwlZ5TllaEYaD15hngGOAfJNlYVV+vqj0L2rwB2FlV/6OqvgP8m1kHSfLPgVcB/773jKUV%0AYBhoXamq/w38GrAD+GaSjyU5aUGzTcDDE8d8G/i/bcdIcjHw74AtVfWt3pOWVoBhoHWnqm6qqp8G%0ATh1v+sCCJo8Cpzx7J8nzGH0ovKQkW4DfA15fVfcNMF1pRRgGWleSnDX+wPgY4P8B32Z06WjSJ4Cf%0AS3Juku9j9C6iTd+vAf4z8Iaq+tyA05aWnWGg9ebvAu8H/grYD7wQuGaywfhf9L8CfHzc5nHgm8Df%0ALtH3e4DjgE8neWL8baU/HXb60vIY5JfOktwAvB44UFU/usj+VwM3A7vHm/5rVf3b3gNLKyDJscBB%0A4Myqemi15yMth6HeGdzI6Ct6Te6qqrPHPwaB1rQkr0/yvHEQ/BZwr0Gg72WDhEFV3Q389RLNMsRY%0A0grZyugS0SPAZuDNAEkmLwE9PnH76tWcrNTXYH+bKMlpwC0Nl4n+hNETax9wpd+0kKS1Y+MKjfM5%0A4NSq+pskFwKfBM5aobElSUtYkTCoqicnbn8mye8m+cHFfiEniX9GVZJmVFW9LsUP+dXSMOVzgSQn%0ATtw+h9Hlqam/mVlV/lSxffv2VZ/DWvixDtbCWjT/DGGQdwZJPgbMAS9I8nVgO6O//1JVdT3wxiS/%0ABDzN6Jd83jzEuJKkYQwSBlX1T5fY/yFGfwVSkrQG+RvIa9jc3NxqT2FNsA5HWIsjrMWw1tz/9jJJ%0ArbU5SdJaloRaQx8gS5KeowwDSZJhIEkyDCRJGAaSJAwDSRKGgSQJw0CShGEgScIwkCRhGEiSMAwk%0ASRgGkiQMA0kShoEkCcNAkoRhIEnCMJAkYRhIkjAMJEkYBpIkDANJEoaBJAnDQJKEYSBJwjCQJDFQ%0AGCS5IcmBJPc2tPlgkl1JvpjklUOMK0kaxlDvDG4ELpi2M8mFwOaqegnwDuDDA40rSRrAxiE6qaq7%0Ak5zW0GQr8Afjtn+R5PgkJ1bVgcUa79nzEO997++zb98hTj55A+9739s444ym7tv30dR3233HH/84%0AVRt5/PHnt+5jljVNG2vhuJdf/lquv/72mebU1K7tOWi7li7nseu5b1v3yZot59y71rnL/NqONcQa%0Au/TXtMamx3ffmi13bYc+B11qMaiqGuQHOA24d8q+W4Cfmrh/O3D2lLa1efMVBU8WVMGTtXnzFbV7%0A995qa/fuvYv2ceedd0/te9oxR+/bW/DumfpoGrd57pNjLRz3vtq48a0zzml6uzb1W6pObfuY9bwt%0Ade7b132yZss596517jK/dmMNVetZ+2s+B02P7341G+bcD/u8aq7Z7LWYNHop7/ka3reDwx0NGAZH%0AilCHi7Ft247Gwk7atm3Hon2cfvovTO172jFH72vbrt24zXNvGrfLnKa3a1O/perUto9Zz9tS5759%0A3Vdq7l3H6XLcsDWb5XnWpr/mc7B8NRvm3A/7vGquWb/+hgiDQS4TtbAP+OGJ+6eMt03xmxO354A5%0A9u8/1H6wfYeAYxdsPZaDB49ddPv+/YcY5VCbfdsXGbG5j6Zxm+c+OdbCcae16zb36XNo6q9bH9N0%0AOabpuKPr3q7//nPvWucu82s3VvN82x83a3/N56Dp8b34fNrWbJhzP+zzaqH2z/Wj+5ufn2d+fr6x%0A/1kNGQYZ/yxmJ/BO4ONJzgUO1pTPC0au5LtP3FNs2tT+s+6TT94APHVUHyec8BQHDx69/UjfbffN%0A1sfS4zbNfdrtpnZd5z5tDkuvcfY+jtblmKbjjq57u/6HmXuXcbrOb7iazfI8a9Pf0udgeWo23Lkf%0A7nm1UPvn+tH9zc3NMTc3d/j+tdde2zhWK33fWozeofAxYD/wt8DXgbcz+tbQ5RNtrgO+BvwlUy4R%0A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%0A+P96j4wSXE5pjAAAAABJRU5ErkJggg==)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0AB2Gcz6IS3Kt+AAAAAElFTkSuQmCC)

&lt;/div&gt;



&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[6\]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

    def code_demodulate(signal, carrier, stretch=5):
        y = np.multiply(signal, carrier)
        ysubs = np.split(y, len(y)/5)
        ysubs = map(sum, ysubs)
        ysubs = map(lambda x:max(-1, x), ysubs)
        ysubs = map(lambda x:min(1, x), ysubs)    
        return ysubs

    x = code_demodulate(out_comb, c_1)
    plot_sig(x, 'sig_1 recovered')
    plot_sig(sig_1, 'sig_1 expected')

    x = code_demodulate(out_comb, c_2)
    plot_sig(x, 'sig_2 recovered')
    plot_sig(sig_2, 'sig_2 expected')

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;div class="output_wrapper"&gt;

&lt;div class="output"&gt;




&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0AkbbtXyc5IMlBVbVzscY33HAjb3/7n7F9+y4OOOA2qjZy220P5uCDN/Da1z6Ps8++aNF173jHq3n8%0A4yeVsXffC/ub1MfC7Xa3G7d8lv0YV1PX2ie1Gx2r67jTzGeX+et63Poeqz719tmPIWof4vzp099y%0A1N7nPJvUbtbj2/c117WmrvPZp/Zpz8FBVNUgP8BhwFVj1l0APGvk+UXAkWPa1uGHv7Hg9oJtBae2%0Aj6vg6tq48VVj1t1ehx/+xtq6dVuNs3XrtpG+F/Y3vo99t2vaXXrp5Ysu37p124JtptmPxWvad6w+%0A7UbH6jbudPPZZf66Hbe+x2qSPsdx9v2d5lj1OX/69Lcctfc5zya1m/X49n3Ndaup63zOem52PQeb%0At/IZ38Nn7eCejgYMgz07Oj/yeOHzheuaiTnppPmxE37SSZP6G9/Hvts17R73uF8bu/3e20yzH13H%0A6tNu+nGnm88u89d3zqevr2u9k47j7Ps7zbHqc/706W85au9zns32ep58fPu+5rrV1HU+Zz03u56D%0AQ4TBIJeJOtgOPHbk+SHtsjH+48jjK4G59vEuYP/28RmLbLc/O3bsGl/E9tHtF/Y3vo99t2va3Xrr%0A/mO3r2JCrZP2o+tYfdqNjtVt3Onmc/Ft9m7X7bj1PVaT9DmOXbbvW/sw50+f/paj9j7n2aR2i9c3%0AyeTzrM+68TV1nc+upj+3trQ/wxnyq6VpfxZzPvBKgCRHA7fWmPsFjdOA+fbn50eWbwDuGHk++rh5%0AvmnT+F06+OCF2y98vngf+27XtDvwwDvGbr/vNpPGXbqmfcfq2266caebz8W3mTwXXbeZvr6u9U46%0Ajl2271v7cOdPn/6Grr3vedb/9bzQcK+5pWvqOp9dTX985tjzHnlarzH3MetHi2oi8uPADuDHwLeB%0A19B8a+i1I23OAr4FfI0xl4jadguuiU26VnpvuWcwzX4s5z2DhWOtxj2DbsfNewbTnD9r7Z7BNOfZ%0AuHZDHN++r7mla/KewQr8ALV167b22ljV5s1/UMcf/6aC5nrZpZdePnZdlwMx2vfC/ib1sXC73e3G%0ALV+4bpr9GFdT19ontRsdq+u408xnl/nretz6Hqs+9fbZjyFqH+L86dPfctTe5zyb1G7W49v3Nde1%0Apq7z2af2ac/BIcIg1bwBrxlJandNSZN9Cx8vta7bOOP7m2a7Ltv33Y+uY/Vp12fcSfrMX98571Pf%0A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%0Amrqe+31q7/tamklVzfwDXAIcOWbdrwNnjzw/GXj/hL4Kbq/DD39jbd26rbrYunVbHX74GwtuL6iC%0Aq2vjxleNPD915PHife/bx+Lb7Nuu27o+uva3/OOeOmFum7EuvfTyJY7BbPM+eZtJx3uI49i1jz61%0Az3b+9O1v6NqHNrm+pc/Hlamp67k/Xe19XkvNW/mM7+NLNoAvAleN/Hy9/e+LR9pcMmwYNDt80knz%0AnQ7SSSfNj0xUFSx8Pvp48b737WPxbfZt121dH137W/5xJ81ts/5xj/u1Tu36zvvkbSb1McRxnK1d%0A12PV5zj27W/o2oc2ub7pz7Plqanrub/8r6UhwmBjh08Oz5/xw8d24NCR54e0yyaYB+CKKy5hy5Zn%0AMzc3N3mA7buA/UeWLHy+/94bsD87duxaoo/Ft6nqt66PfWtavL+u7fqPO2lum/W33rp/p3Z9533y%0ANpP6GOI4ztZucu3dahqnb39D1z60yefF9OfZ8tTUjLX0ub8cr6UrueKKi5mfr67lL2nIr5aOu29w%0AJXBEksOS7Ae8Ajh/clfzwGkcc8xzlgwCgIMP3gDcMbJk9PmZC9YB3MGmTXvv+t59jN9m37G6reuj%0Aa3/LO+7CuVh8rAMPvKNTu77zPn6bhWOdOebx3v11P45d++hbe7eaxunb39C1D218fd3Ox+Wvac9Y%0Ak8/96Wvv9lr6eY455jnMz88zPz8/1X6MNcvHCuAE4CbgTuA7wBfa5Y8BPjfS7ljgm8D1wOlL9FnT%0AXvebfA15W01/PXT8NuvvnsHCuVjOewZ9jtWk4z3EcezaR9/a18I9g9lrH9r4+rqdj2vnnsH0ta/W%0APYM0/awdSeqkk+Z5xztezeMff1jn7W644Ube/vY/Y8eOXWzatIHXvvZ5nH32RezYsYuHPvQ2qjby%0Aox89mE2bNozte7SPSdssHKvruj669rec4y6ci9G5HR1r0jEYYt4n7e+44z3EcezaR9/aZz1/+vY3%0AdO1DG1df1/NxuWvqeu73qX3a11ISqmrStzqXtCbDYK3VJElr2RBh4D9HIUkyDCRJhoEkCcNAkoRh%0AIEnCMJAkYRhIkjAMJEkYBpIkDANJEoaBJAnDQJKEYSBJwjCQJGEYSJIwDCRJGAaSJAwDSRKGgSQJ%0Aw0CShGEgScIwkCRhGEiSMAwkSRgGkiQMA0kShoEkiRnDIMlLk3wjyd1JjpzQbluSryX5SpL/M8uY%0AkqThzfrJ4OvAS4BLl2i3C5irqmdU1VEzjrlubNmyZbVLWBOchz2ciz2ci2HNFAZV9c2quh7IEk0z%0A61jrkSd7w3nYw7nYw7kY1kq9QRfwxSRXJvmdFRpTktTRxqUaJPkicNDoIpo3939bVRd0HOeYqvpO%0AkkfShMI1VXX59OVKkpZDqmr2TpJLgDdW1Zc7tD0D+FFVvWfM+tkLkqR1pqqWulw/0ZKfDKawaCFJ%0AHgxsqKrbk+wPvAA4c1wns+6QJGl6s3619IQkNwFHA59L8oV2+WOSfK5tdhBweZKvAF8CLqiqC2cZ%0AV5I0rEEuE0mS7t3WzNc9kxyb5Nok1yV582rXs5KSHJLk4iR/m+TrSV7fLn9YkguTfDPJ/0hywGrX%0AulKSbEjy5STnt8/X5VwkOSDJJ5Nc054fv7CO5+LU9o9cr0rysST7rZe5SHJOkp1JrhpZNnbfk7wl%0AyfXtefOCLmOsiTBIsgE4C3gh8DTgxCRPXt2qVtRPgH9TVU8DfhH4vXb/TwcuqqonARcDb1nFGlfa%0AG4CrR56v17l4H/D5qnoK8HPAtazDuUiyCfh94Miq+lma+50nsn7m4lya98dRi+57kqcCLweeAhwH%0AfDDJkvdi10QYAEcB11fVjVV1F3AesHmVa1oxVXVLVX21fXw7cA1wCM0cfLht9mHghNWpcGUlOQT4%0AFeBPRxavu7lI8lDgl6rqXICq+klV/ZB1OBet+wH7J9kIPAjYzjqZi/ar+D9YsHjcvh8PnNeeL9uA%0A62neYydaK2FwMHDTyPOb22XrTpLHAU+nudl+UFXthCYwgEetXmUr6k+A02j+nmW39TgXjwe+m+Tc%0A9pLZ2e2389bdXFTVDuDdwLdpQuCHVXUR63AuRjxqzL4vfD/dTof307USBgKSPAT4FPCG9hPCwrv7%0A9/m7/UleBOxsPylN+mh7n58LmkshRwIfqKojgTtoLg2sx/PiQJrfhA8DNtF8QjiJdTgXE8y072sl%0ADLYDh448P6Rdtm60H30/BXy0qj7bLt6Z5KB2/aOBv1+t+lbQMcDxSbYCnwCek+SjwC3rcC5uBm6q%0Aqv/bPv80TTisx/PiecDWqvp+Vd0N/CXwLNbnXOw2bt+3A48dadfp/XSthMGVwBFJDkuyH/AK4PxV%0Armml/Vfg6qp638iy84FXt49fBXx24Ub3NVX11qo6tKqeQHMeXFxV/xK4gPU3FzuBm5I8sV30XOBv%0AWYfnBc3loaOTPLC9Gfpcmi8YrKe5CHt/Wh637+cDr2i/bfV44Ahgyf91wJr5O4Mkx9J8c2IDcE5V%0AvXOVS1oxSY4BLqP5J8Gr/XkrzQH8C5qUvxF4eVXdulp1rrQkz6b5Z06OT/Jw1uFcJPk5mhvp9we2%0AAq+huZG6HufiDJpfEO4CvgL8NvBTrIO5SPJxYA54BLATOAP4DPBJFtn3JG8B/hXNXL2hyx/6rpkw%0AkCStnrVymUiStIoMA0mSYSBJMgwkSRgGkiQMA0kShoEkCcNAkgT8f/oDFXv1UyDeAAAAAElFTkSu%0AQmCC)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0A73znX7F9+y723/9WqlZz660P5aCDVnHaac/h3HMvnnfdu971Gg4/fFIZ9+57tL9JfYxut7vduOWz%0A7Me4mtrWPqnd8Fhtx51mPtvMX9vj1vVYdam3y370UXsf50+X/haj9i7n2aR2sx7frq+5tjW1nc8u%0AtU97Dvaiqnr5AQ4Drhyz7kLgGUPPLwaOGdO21q49o+D2gm0FpzePq+DqWr361WPW3V5r155RW7Zs%0Aq3G2bNk21Pdof+P72Hu7QbtLLrls3uVbtmwb2Waa/Zi/pr3H6tJueKx24043n23mr91x63qsJuly%0AHGff32mOVZfzp0t/i1F7l/NsUrtZj2/X11y7mtrO56znZttzcPBWPuN7+Kwd3NNRj2GwZ0fnhh6P%0APh9dN5iYDRvmxk74hg2T+hvfx97bDdo9/vEvHrv9vbeZZj/ajtWl3fTjTjefbeav65xPX1/beicd%0Ax9n3d5pj1eX86dLfYtTe5Tyb7fU8+fh2fc21q6ntfM56brY9B/sIg14uE7WwHThk6PnBzbIx/uvQ%0A48uBdc3jXcCa5vHGebZbw44du8YXsX14+9H+xvex93aDdjffvGbs9lVMqHXSfrQdq0u74bHajTvd%0AfM6/zb3btTtuXY/VJF2OY5vtu9bez/nTpb/FqL3LeTap3fz1TTL5POuybnxNbeezrenPrc3NT3/6%0A/Gppmp/5bAJeBZDkOODmGnO/YOBMYK75efrQ8lXAHUPPhx8Pnh944PhdOuig0e1Hn8/fx97bDdo9%0A4hF3jN1+720mjbtwTXuP1bXddONON5/zbzN5LtpuM319beuddBzbbN+19v7Ony799V171/Os++t5%0AVH+vuYVrajufbU1/fNax5z3yzE5j7mXWjxY1iMiPATuAfwZ+ALyWwbeGThtqcw7wfeDbjLlE1LQb%0AuSY26VrpfeWewTT7sZj3DEbHWop7Bu2Om/cMpjl/lts9g2nOs3Ht+ji+XV9zC9fkPYN98APUli3b%0AmmtjVevX/2GddNJ/KBhcL7vkksvGrmtzIIb7Hu1vUh+j2+1uN2756Lpp9mNcTW1rn9RueKy2404z%0An23mr+1x63qsutTbZT/6qL2P86dLf4tRe5fzbFK7WY9v19dc25razmeX2qc9B/sIg9TgDXjZSFK7%0Aa0oG2Tf6eKF17cYZ398027XZvut+tB2rS7su407SZf66znmX+hbqc9q++669j/OnS3+LUXuX82zW%0A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)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0AkjSA9UN0UlVXJTmspclG4CNN279Lsn+SA6tq53yNb7rpZt7xjr9m+/ZdHHzwOt75zldxxBFt3Xfv%0Ao63vrtv23/9OqtZz550P7dzHYo5p0lhzxz399Ody7rmXLmpObe26noOux9LnPPY9913rPl6zpZx7%0A3zr3mV/XsYY4xj79tR1j2+t72potdW2HPgd9ajGoqhrkARwGXDNh28XAb4w9vxQ4ZkLbOvLINxXc%0AVVAFd9WRR76ptm7dVl1t3bpt3j6uuOKqiX1P2mfvbdsK3rioPtrGbZ/7+Fhzx7221q8/bZFzmtyu%0AS/0WqlPXPhZ73hY6993rPl6zpZx73zr3mV+3sYaq9WL7az8Hba/v6Wo2zLkf9n3VXrPF12Lc6KN8%0Ays/waTu4t6MBw2BPEereYpxyyubWwo475ZTN8/Zx+OG/M7HvSfvsva1ru27jts+9bdw+c5rcrkv9%0AFqpT1z4We94WOvfd675cc+87Tp/9hq3ZYt5nXfprPwdLV7Nhzv2w76v2mk3X3xBhMMhlog62A48b%0Ae35Is26C/zy2PAPMsGPHru6Dbd8F7Dtn7b7ccce+867fsWMXoxzqsm3TPCO299E2bvvcx8eaO+6k%0Adv3mPnkObf3162OSPvu07bd33bv1P/3c+9a5z/y6jdU+3+77Lba/9nPQ9vqefz5dazbMuR/2fTVX%0A9/f63v3Nzs4yOzvb2v9iDRkGaR7zuQh4HfCJJMcBd9SE+wUjZ3DfE3c3GzZ0v9d98MHrgLv36uOA%0AA+7mjjv2Xr+n767bFtfHwuO2zX3Sclu7vnOfNIeFj3Hxfeytzz5t++1d9279DzP3PuP0nd9wNVvM%0A+6xLfwufg6Wp2XDnfrj31Vzd3+t79zczM8PMzMy9z88666zWsTqZ9qvF6BsKFwA7gH8Bvgu8mtGv%0Ahk4fa3MO8B3gH5hwiahpt8rvGVQt3z2DuWNNumewmDl5z2B55r5c9wy6jTVUrRfb38LnYNLrezXc%0AMxj2fbVwzRZXi3EMcJlokDAY8gHU1q3bmutpo+tqfV6gk/po67vrto0b/6xOPPHNi+pjMcc0aay5%0A415xxVWLnlNbuy71W8yx9DmPfc9917qP12wp5963zn3m13WsIY6xT39tx9j2+p62Zktd26HPQZ9a%0A7DZEGGTUz+qRpHbPKRnl4nT9zd9HW99dt/XpYzHHNGmsuX30mVPXefStU5920+7Ttl9bzYaexxB1%0A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)

&lt;/div&gt;



&lt;/div&gt;



&lt;div class="output_area"&gt;

&lt;div class="prompt"&gt;

&lt;/div&gt;




&lt;div class="output_png output_subarea"&gt;

![](data:image/png;base64,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%0ALgBOnLQxybOAdVX1i8CrgfcNNK4kaQCrh+ikqi5PsralyXrgA03bf0xycJJDqmrnfI23br2Ot771%0AL9m+fReHHbaKt73tFRx5ZFv33fto67vrtoMPvpWq1dx66wM697GYY5o01txxTz/96Zx33iWLmlNb%0Au67noOux9DmPfc9917qP12xfzr1vnfvMr+tYQxxjn/7ajrHt+T1tzfZ1bYc+B31qMaiqGuQHWAtc%0ANWHbRcCTx+5fAhw7oW2tW3dGwe0FVXB7rVt3Rm3Zsq262rJl27x9XHrp5RP7nrTP3tu2FbxhUX20%0Ajds+9/Gx5o77rVq9+uWLnNPkdl3qt1Cduvax2PO20LnvXvfxmu3Lufetc5/5dRtrqFovtr/2c9D2%0A/J6uZsOc+2FfV+01W3wtxo3eyqd8D5+2g7s7GjAM9hSh7i7Ghg2bWgs7bsOGTfP2ccQRz5/Y96R9%0A9t7WtV23cdvn3jZunzlNbtelfgvVqWsfiz1vC5377nXfX3PvO06f/Yat2WJeZ136az8H+65mw5z7%0AYV9X7TWbrr8hwmCQZaIOtgOPGLt/ePPYBP9j7PYMMMOOHbu6D7Z9F3DgnEcP5OabD5z38R07djHK%0AoS7bNs4zYnsfbeO2z318rLnjTmrXb+6T59DWX78+JumzT9t+e9e9W//Tz71vnfvMr9tY7fPtvt9i%0A+2s/B23P7/nn07Vmw5z7YV9Xc3V/re/d3+zsLLOzs639L9aQYZDmZz6bgdcAH0lyPHBzTbheMHIm%0A9zxxd7BmTfdr3Ycdtgq4Y68+HvSgO7j55r0f39N3122L62PhcdvmPul2W7u+c580h4WPcfF97K3P%0APm377V33bv0PM/c+4/Sd33A1W8zrrEt/C5+DfVOz4c79cK+rubq/1vfub2ZmhpmZmbvvn3POOa1j%0AdTLtR4vRJxQ+BOwA/hW4Hnglo28NnT7W5lzgu8DXmLBE1LRb5tcMqvbfNYO5Y026ZrCYOXnNYP/M%0AfX9dM+g21lC1Xmx/C5+DSc/v5XDNYNjX1cI1W1wtxjHAMtEgYTDkD1Bbtmxr1tNG62p9nqCT+mjr%0Au+u29et/r04++fcX1cdijmnSWHPHvfTSyxc9p7Z2Xeq3mGPpcx77nvuudR+v2b6ce98695lf17GG%0AOMY+/bUdY9vze9qa7evaDn0O+tRityHCIKN+lo8ktXtOySgXp+tv/j7a+u66rU8fizmmSWPN7aPP%0A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%0AAABJRU5ErkJggg==)

&lt;/div&gt;



&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;div class="cell border-box-sizing text_cell rendered"&gt;

&lt;div class="prompt input_prompt"&gt;

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="text_cell_render border-box-sizing rendered_html"&gt;

Perfect.  


&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div class="cell border-box-sizing code_cell rendered"&gt;

&lt;div class="input"&gt;

&lt;div class="prompt input_prompt"&gt;

In \[ \]:

&lt;/div&gt;

&lt;div class="inner_cell"&gt;

&lt;div class="input_area"&gt;

&lt;div class="highlight hl-ipython2"&gt;

&lt;/div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;



&lt;/div&gt;</content><category term="posts"/><category term="computer"/><category term="python"/><category term="code"/></entry><entry><title>Reading Lecroy Binary Waveform in Python</title><link href="/reading-lecroy-binary-waveform-in-python.html" rel="alternate"/><published>2016-05-07T22:29:00+10:00</published><updated>2016-05-07T22:29:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2016-05-07:/reading-lecroy-binary-waveform-in-python.html</id><summary type="html">&lt;p&gt;I needed to read Lecroy binary waveforms files recently, and &lt;a href="http://qtwork.tudelft.nl/gitdata/users/guen/qtlabanalysis/analysis_modules/general/lecroy.py"&gt;the one python script I had found&lt;/a&gt; didn't read them properly due to improper handling of 16 bit samples.  &lt;/p&gt;
&lt;p&gt;I wrote an alternative &lt;a href="https://github.com/freespace/dphil-data-tools/blob/master/lecroy.py"&gt;lecroy.py&lt;/a&gt; that should be a drop-in replacement. It  handles 16 bit waveforms and exports a LecroyBinaryWaveform …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I needed to read Lecroy binary waveforms files recently, and &lt;a href="http://qtwork.tudelft.nl/gitdata/users/guen/qtlabanalysis/analysis_modules/general/lecroy.py"&gt;the one python script I had found&lt;/a&gt; didn't read them properly due to improper handling of 16 bit samples.  &lt;/p&gt;
&lt;p&gt;I wrote an alternative &lt;a href="https://github.com/freespace/dphil-data-tools/blob/master/lecroy.py"&gt;lecroy.py&lt;/a&gt; that should be a drop-in replacement. It  handles 16 bit waveforms and exports a LecroyBinaryWaveform class that also provides additional metadata. It supports saving to CSV for binary to text conversion.&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="software"/><category term="oss"/></entry><entry><title>Arduino-MK with Sparkfun Pro Micro 3.3V</title><link href="/arduino-mk-with-sparkfun-pro-micro-33v.html" rel="alternate"/><published>2016-04-16T22:48:00+10:00</published><updated>2016-04-16T22:48:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2016-04-16:/arduino-mk-with-sparkfun-pro-micro-33v.html</id><summary type="html">&lt;p&gt;&lt;a href="https://github.com/sudar/Arduino-Makefile"&gt;Arduino-Makefile&lt;/a&gt; needed coaxing to in order to compile code targeting the &lt;a href="https://www.sparkfun.com/products/12587"&gt;SparkFun Pro Micro 3.3V&lt;/a&gt;. A major source of headache is the requirement for &lt;code&gt;BOARD_SUB&lt;/code&gt; which isn't documented and required diving into the source code, and also the fact the Pro Micro has 2 PIDs for each variant (5V …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://github.com/sudar/Arduino-Makefile"&gt;Arduino-Makefile&lt;/a&gt; needed coaxing to in order to compile code targeting the &lt;a href="https://www.sparkfun.com/products/12587"&gt;SparkFun Pro Micro 3.3V&lt;/a&gt;. A major source of headache is the requirement for &lt;code&gt;BOARD_SUB&lt;/code&gt; which isn't documented and required diving into the source code, and also the fact the Pro Micro has 2 PIDs for each variant (5V and 3.3V).&lt;/code&gt;&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;Hope this will help someone in the same position as me. This makefile is meant for use on Debian Linux, with Arduino-MK installed via &lt;code&gt;apt-get install arduino-mk&lt;/code&gt;.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;MONITOR_PORT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;ttyACM0&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;point&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sparkfun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;definitions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;installed&lt;/span&gt;
&lt;span class="nx"&gt;SPF_AVR_PATH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HOME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arduino15&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;SparkFun&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;hardware&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;avr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m m-Double"&gt;1.1.3&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;own&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;arduino&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;way&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;advanced&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;than&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;1.0&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;installed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;arduin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;core&lt;/span&gt;
&lt;span class="nx"&gt;ARDUINO_DIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HOME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;arduino&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m m-Double"&gt;1.6.7&lt;/span&gt;

&lt;span class="nx"&gt;USER_LIB_PATH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;HOME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Arduino&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;libraries&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;needed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stdint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;exposes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;needed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;defines&lt;/span&gt;
&lt;span class="nx"&gt;CPPFLAGS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;gnu&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;needed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;don&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;__cxa_guard_acquire&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;issues&lt;/span&gt;
&lt;span class="nx"&gt;CPPFLAGS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;fno&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;threadsafe&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;statics&lt;/span&gt;


&lt;span class="nx"&gt;BOARD_TAG&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;promicro&lt;/span&gt;
&lt;span class="nx"&gt;BOARD_SUB&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;MHzatmega32U4&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;also&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Arduino&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;isn&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;clever&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;enough&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;yet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;properly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;extract&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;from&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;boards&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;specify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;here&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;
&lt;span class="nx"&gt;USB_PID&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x9204&lt;/span&gt;
&lt;span class="nx"&gt;ALTERNATE_CORE&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;promicro8&lt;/span&gt;
&lt;span class="nx"&gt;ALTERNATE_CORE_PATH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SPF_AVR_PATH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;BOOTLOADER_PATH&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;caterina&lt;/span&gt;
&lt;span class="nx"&gt;BOOTLOADER_FILE&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Caterina&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;promicro8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt;
&lt;span class="nx"&gt;ISP_PROG&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;usbasp&lt;/span&gt;


&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;arduino&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Arduino&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="arduino"/><category term="software"/><category term="oss"/><category term="linux"/></entry><entry><title>Method Forwarding in Objective-C Pitfall</title><link href="/method-forwarding-in-objective-c-pitfall.html" rel="alternate"/><published>2016-04-12T20:01:00+10:00</published><updated>2016-04-12T20:01:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2016-04-12:/method-forwarding-in-objective-c-pitfall.html</id><summary type="html">&lt;p&gt;A common pitfall of trying to use message forwarding in Objective-C is forgetting to implement  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;in addition to  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (void)forwardInvocation:(NSInvocation *)anInvocation&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;Another problem is that sometimes calling objects will use  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (BOOL)respondsToSelector:(SEL)aSelector&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;to determine if your proxy object can respond to a particular …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A common pitfall of trying to use message forwarding in Objective-C is forgetting to implement  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;in addition to  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (void)forwardInvocation:(NSInvocation *)anInvocation&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;Another problem is that sometimes calling objects will use  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;- (BOOL)respondsToSelector:(SEL)aSelector&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;to determine if your proxy object can respond to a particular selector. The problem is that even if you forward that selector, because the message isn't actually sent, the default implementation of &lt;code&gt;respondsToSelector&lt;/code&gt; will return &lt;code&gt;NO&lt;/code&gt;, causing the forwarding to fail. Therefore you should also override &lt;code&gt;respondsToSelector&lt;/code&gt;.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="objective-c"/><category term="code"/><category term="software"/><category term="ios"/></entry><entry><title>Permission Denied When Programming Arduino Micro/SparkFun Pro Micro</title><link href="/permission-denied-when-programming-arduino-microsparkfun-pro-micro.html" rel="alternate"/><published>2016-03-23T01:47:00+11:00</published><updated>2016-03-23T01:47:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2016-03-23:/permission-denied-when-programming-arduino-microsparkfun-pro-micro.html</id><summary type="html">&lt;p&gt;I recently started having trouble with Arduino 1.6.x not being able to program Arduino Micro or SparkFun Pro Micro, with avrdude complaining about permission denied when trying to open /dev/ACM0.  &lt;/p&gt;
&lt;p&gt;The usual solutions to this is to add oneself to the dialup group, or mess around in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently started having trouble with Arduino 1.6.x not being able to program Arduino Micro or SparkFun Pro Micro, with avrdude complaining about permission denied when trying to open /dev/ACM0.  &lt;/p&gt;
&lt;p&gt;The usual solutions to this is to add oneself to the dialup group, or mess around in /etc/udev/rules.d/99-arduino.rules.  &lt;/p&gt;
&lt;p&gt;None of these worked for me. However Arduino is able to program the micros fine if I run it as root, which clued me into that fact that there is some finite time between the kernel creating /dev/ttyACM0 and udev rules having effect. Specifically, udevd is a userspace daemon, and therefore necessary runs sometime after the kernel as created the relevant device node.  &lt;/p&gt;
&lt;p&gt;The problem is thus: Arduino IDE opens /dev/ttyACM0 at 1200bps and immediately closes it. This is causes the ATmega32u4 to reset itself, causing the serial port to disappear. When the bootloader runs, it presents itself as a usb-serial device, and /dev/ttyACM0 appears again. Reappearance of /dev/ttyACM0 causes the Arduino IDE to launch avrdude, which immediately tries to open /dev/ttyACM0 and fails because udev hasn't had time to process all the rules and assign the correct permissions etc.  &lt;/p&gt;
&lt;p&gt;The solution then is to introduce a delay before running avrdude, or even better, let udev let us known when it is done, which is much more robust. This can be done using  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;udevadm settle -t 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which waits for the udev to "settle", and the -t 1 specifies a maximum wait time of 1 second.  &lt;/p&gt;
&lt;p&gt;I hit upon the idea of wrapping avrdude in a shellscript and then adding the above line before avrdude, and that was when I discovered that hardware/tools/avr/bin/avrdude is already a shellscript! This made things much easier.   &lt;/p&gt;
&lt;p&gt;My Arduino IDE's avrdude script now looks like:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hardware&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;avrdude&lt;/span&gt;
&lt;span class="cp"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="n"&gt;udevadm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;settle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;`dirname &amp;quot;&lt;/span&gt;&lt;span class="n"&gt;$0&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;`/../lib/&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;$0&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;`dirname &amp;quot;&lt;/span&gt;&lt;span class="n"&gt;$0&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;`/avrdude_bin&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;$@&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Programming of Arduino Micro and SparkFun Pro Mini is now flawless under Xubuntu 15.10.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="arduino"/><category term="software"/><category term="oss"/><category term="linux"/></entry><entry><title>Notes on Migrating a Linux Install</title><link href="/notes-on-migrating-a-linux-install.html" rel="alternate"/><published>2016-03-23T00:42:00+11:00</published><updated>2016-03-23T00:42:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2016-03-23:/notes-on-migrating-a-linux-install.html</id><summary type="html">&lt;p&gt;Some issues I ran into when trying to move a Linux install from a 500 GB drive to a smaller 120 G SSD:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When duplicating the filesystem, make sure that &lt;strong&gt;/proc&lt;/strong&gt; exists, otherwise when you boot the new drive the kernel will complaint that /proc is missing and it can't …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;Some issues I ran into when trying to move a Linux install from a 500 GB drive to a smaller 120 G SSD:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When duplicating the filesystem, make sure that &lt;strong&gt;/proc&lt;/strong&gt; exists, otherwise when you boot the new drive the kernel will complaint that /proc is missing and it can't create the virtual file system&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;grub-rescue&lt;/strong&gt;, &lt;strong&gt;(hd0,msdos2)&lt;/strong&gt; is &lt;strong&gt;/dev/sda2&lt;/strong&gt;, and &lt;strong&gt;(hd0,msdos1)&lt;/strong&gt; is &lt;strong&gt;/dev/sda1&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;When specifying &lt;/span&gt;&lt;strong&gt;initrd&lt;/strong&gt;&lt;span style="font-family: inherit;"&gt; be sure not to accidentally select the &lt;/span&gt;&lt;strong&gt;vmlinuz&lt;/strong&gt;&lt;span style="font-family: inherit;"&gt; image again&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: inherit;"&gt;After you have fixed grub and find that booting is taking longer than expected, check that the UUID in &lt;/span&gt;&lt;strong&gt;/etc/initramfs-tools/conf.d/resume&lt;/strong&gt; is the UUID of your swap partition. Check using &lt;strong&gt;sudo blkid&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="oss"/><category term="linux"/></entry><entry><title>Thinkpad Mute Buttons and Xubuntu</title><link href="/thinkpad-mute-buttons-and-xubuntu.html" rel="alternate"/><published>2016-03-23T00:41:00+11:00</published><updated>2016-03-23T00:41:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2016-03-23:/thinkpad-mute-buttons-and-xubuntu.html</id><summary type="html">&lt;p&gt;I recently acquired a used Lenovo X220 for use as a linux laptop, and needed the following in my openbox configuration XML to make the hardware speaker and mic mute buttons work:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Modified for X220 --&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;keybind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;XF86AudioMute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Execute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;command&amp;gt;&lt;/span&gt;pactl&lt;span class="w"&gt; &lt;/span&gt;set-sink-mute&lt;span class="w"&gt; &lt;/span&gt;0&lt;span class="w"&gt; &lt;/span&gt;toggle&lt;span class="nt"&gt;&amp;lt;/command&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/keybind&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;keybind …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;I recently acquired a used Lenovo X220 for use as a linux laptop, and needed the following in my openbox configuration XML to make the hardware speaker and mic mute buttons work:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Modified for X220 --&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;keybind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;XF86AudioMute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Execute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;command&amp;gt;&lt;/span&gt;pactl&lt;span class="w"&gt; &lt;/span&gt;set-sink-mute&lt;span class="w"&gt; &lt;/span&gt;0&lt;span class="w"&gt; &lt;/span&gt;toggle&lt;span class="nt"&gt;&amp;lt;/command&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/keybind&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;keybind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;key=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;XF86AudioMicMute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Execute&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;command&amp;gt;&lt;/span&gt;pactl&lt;span class="w"&gt; &lt;/span&gt;set-source-mute&lt;span class="w"&gt; &lt;/span&gt;1&lt;span class="w"&gt; &lt;/span&gt;toggle&lt;span class="nt"&gt;&amp;lt;/command&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/keybind&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Sources and sinks can be discovered using:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pactl list sources
pactl list sinks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For me there was only one sink, and two sources, the first of which is some kind of virtual source that monitors the microphone, while the second source is the microphone itself.  &lt;/p&gt;
&lt;p&gt;Something that is interesting is that both speaker and mic mute buttons have a central light that lights up when mute is active, and this seems tied to the hardware. This makes me trust that when the mute buttons are used they actually do something.  &lt;/p&gt;
&lt;p&gt;Hope this helps some people.  &lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="oss"/><category term="linux"/></entry><entry><title>On the Use of I/Q Signals</title><link href="/on-the-use-of-iq-signals.html" rel="alternate"/><published>2015-10-04T23:09:00+11:00</published><updated>2015-10-04T23:09:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2015-10-04:/on-the-use-of-iq-signals.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;All signals are complex, that is they have the form of &lt;div class="math"&gt;$$x(t)=A\exp(i\omega t)$$&lt;/div&gt;. I/Q presentation of a signal fully captures this by storing the real component in the &lt;strong&gt;I&lt;/strong&gt;, the in-phase signal, and the complex component in &lt;strong&gt;Q&lt;/strong&gt;, the quadrature signal.&lt;/li&gt;
&lt;li&gt;When we force …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;All signals are complex, that is they have the form of &lt;div class="math"&gt;$$x(t)=A\exp(i\omega t)$$&lt;/div&gt;. I/Q presentation of a signal fully captures this by storing the real component in the &lt;strong&gt;I&lt;/strong&gt;, the in-phase signal, and the complex component in &lt;strong&gt;Q&lt;/strong&gt;, the quadrature signal.&lt;/li&gt;
&lt;li&gt;When we force signals to be purely real, e.g. &lt;span class="math"&gt;\(\cos(\omega t)\)&lt;/span&gt;, we taking the real part of &lt;span class="math"&gt;\(exp(i\omega t)\)&lt;/span&gt;. Because we ignore the imaginary component, we lose information. Specifically, &lt;span class="math"&gt;\(\cos(\omega t)\)&lt;/span&gt; can be the real part of &lt;span class="math"&gt;\(\exp(i\omega t)\)&lt;/span&gt; or &lt;span class="math"&gt;\(\exp(-i\omega t)\)&lt;/span&gt;. We don't know any more.&lt;/li&gt;
&lt;li&gt;This ambiguity is present in the exponential form of &lt;span class="math"&gt;\(\cos\)&lt;/span&gt;: &lt;div class="math"&gt;$$\cos(\omega t) = \frac{\exp(i \omega t) + \exp(-i\omega t)}{2}$$&lt;/div&gt;. Note the presence of the two complex signals whose sum is always purely real as their imaginary parts cancel out. The real part of either complex signal will produce &lt;span class="math"&gt;\(\cos(\omega t)\)&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;This ambiguity is why when you multiply &lt;span class="math"&gt;\(\cos(\omega_0 t)\)&lt;/span&gt; and &lt;span class="math"&gt;\(\cos(\omega_1 t)\)&lt;/span&gt; you end up with &lt;span class="math"&gt;\(\cos[(\omega_0 + \omega_1)t]\)&lt;/span&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;span class="math"&gt;\(\cos[(\omega_0 - \omega_1)t]\)&lt;/span&gt;. In other words, the frequency add as &lt;span class="math"&gt;\(\pm \omega_0 \pm \omega_1\)&lt;/span&gt;, which produces 4 unique combinations that reduces to 2 because &lt;span class="math"&gt;\(\cos\)&lt;/span&gt; is even.&lt;/li&gt;
&lt;li&gt;The result of multiplying real cosines produces two peaks in the frequency spectrum.&lt;/li&gt;
&lt;li&gt;On the other hand, preserving the complex nature of a signal by presenting it as &lt;span class="math"&gt;\(A\exp(i\omega t)\)&lt;/span&gt; means that multiplying two signals together produces a unique result: &lt;div class="math"&gt;$$A_0\exp(i\omega_0 t) \times A_1\exp(i\omega_1 t) = A_0A_1\exp[i(\omega_0 + \omega_1)t]$$&lt;/div&gt;. This is because there is no ambiguity as we have not thrown away any information.&lt;/li&gt;
&lt;li&gt;The result of multiplying complex signals produces one peak in the frequency spectrum.&lt;/li&gt;
&lt;li&gt;This is one of the advantages of working with I/Q data, which preserves the complex nature of signals, and allows us to frequency shift a signal through multiplication without also generating an additional unwanted image of the signal.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;

Cheers,

&lt;/div&gt;

&lt;div&gt;

Steve

&lt;/div&gt;

&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="posts"/><category term="dsp"/><category term="gnu-radio"/><category term="maths"/></entry><entry><title>Simple FM Receiver with GNU Radio and RTL-SDR</title><link href="/simple-fm-receiver-with-gnu-radio-and-rtl-sdr.html" rel="alternate"/><published>2015-10-04T00:11:00+10:00</published><updated>2015-10-04T00:11:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2015-10-04:/simple-fm-receiver-with-gnu-radio-and-rtl-sdr.html</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;div&gt;



&lt;div&gt;

I recently started playing around with software defined radio using a USB TV tuner dongle utilising the popular RTL2832U chipset. After playing around with software like &lt;a href="http://cubicsdr.com/" rel="noreferrer" title="https://www.blogger.com/"&gt;CubicSDR&lt;/a&gt; and &lt;a href="http://gqrx.dk/" rel="noreferrer" title="https://www.blogger.com/"&gt;gqrx&lt;/a&gt; I was somewhat frustrated at the opaqueness of what is going on under the hood. As such I resolved to …&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;div&gt;



&lt;div&gt;

I recently started playing around with software defined radio using a USB TV tuner dongle utilising the popular RTL2832U chipset. After playing around with software like &lt;a href="http://cubicsdr.com/" rel="noreferrer" title="https://www.blogger.com/"&gt;CubicSDR&lt;/a&gt; and &lt;a href="http://gqrx.dk/" rel="noreferrer" title="https://www.blogger.com/"&gt;gqrx&lt;/a&gt; I was somewhat frustrated at the opaqueness of what is going on under the hood. As such I resolved to learn &lt;a href="http://gnuradio.org/redmine/projects/gnuradio/wiki" rel="noreferrer" title="https://www.blogger.com/"&gt;GNU Radio&lt;/a&gt; so I can do the signal processing myself. Starting with a basic FM receiver seems like a good idea, since one of my goals is to receive NOAA APT transmissions, which are FM modulated at 137 MHz.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

## The Radio

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

The image below is the FM radio (&lt;a href="https://drive.google.com/open?id=0B_sOZeAAQg0rUmI5aTdEakZUREU" rel="noreferrer" title="https://www.blogger.com/"&gt;source code&lt;/a&gt;) I built in GNU Radio Companion. GNU Radio Companion is part of GNU Radio that makes it pretty easy to graphically put together a custom signal processing chain and "make" a radio in software. I am not usually a big fan of graphical programming, but in this particular instance I have to admit the going was a lot easier than if I had to do this textually. There is built in support for documenting each block, which is nice, though I wish I had more control over the font used and the size of the text boxes.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;/div&gt;

|  |
|:--:|
| &lt;a href="/media/af65b0_fm_mono.grc.png" rel="noreferrer" style="margin-left: auto; margin-right: auto;" title="/media/af65b0_fm_mono.grc.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhakC4X-SJjjA0u8HjiDfwnT4KnZ1OhgSPE6wS1fmvEPOBBK2ZjzOR3IxxTTjHjaJZ92TAEgEs3Ujy8tGpTMVTvIhx1jiZlzqBxe3at9kwgPBCGXcer_VOsqrPHJs7dWIHsTVMChw/s640/fm-mono.grc.png" data-border="0" width="640" height="334" /&gt;&lt;/a&gt; |
| FM radio created in GNU Radio Companion. |

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

It looks more complicated than it is. Basically, the output from the receiver, which is centred around the central frequency, is down-sampled from 2.4 MHz to 500 KHz, then low-pass filtered and then passed to a FM demodulator module. The output of the FM demodulator is then resampled to 48 KHz and piped to an audio sink, i.e. a sound card.  

All the extra stuff is are GUI controls and visualisations to aid in understanding and debugging.  

This is what it looks like running, tuned a local station at 99.1 MHz, which is BBC Radio 1.  


|  |
|:--:|
| &lt;a href="/media/4eb591_Screen_Shot_2015_10_04_at_12.58.48_am.png" rel="noreferrer" style="margin-left: auto; margin-right: auto;" title="/media/4eb591_Screen_Shot_2015_10_04_at_12.58.48_am.png"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI-4IYGDvuyiDvffWAPmBt64yDAgM9VWt0lTp7bWaxXNu0cygw8kM29VmBh0BSBP02YIco2vj4h7othCP7PLdL2ZPttVu9O9UfsnvaadywwspX-i-9FK_ATRYUqoGAr4GNL9GIvQ/s640/Screen+Shot+2015-10-04+at+12.58.48+am.png" data-border="0" width="640" height="272" /&gt;&lt;/a&gt; |
| Radio in operation. Top-left: FFT of the signal from the receiver; Top-right: resampled signal; Bottom: Low-pass filtered signal. |

&lt;/div&gt;

&lt;div&gt;

There is some rudimentary control over GUI position and size, but it is otherwise brutally utilitarian. However the resulting python file can be modified to fine tune appearances and such I believe. Nonetheless, it is very useful for figuring out where you went wrong.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

Next Step

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

The current goal is to make a NOAA APT specific radio and keep trying for a clean image.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

Cheers,

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;

Steve

&lt;/div&gt;</content><category term="posts"/><category term="computer"/><category term="electronics"/><category term="software"/><category term="gnu-radio"/></entry><entry><title>Porting Seeeduino Xadow to Arduino 1.6.3</title><link href="/porting-seeeduino-xadow-to-arduino-163.html" rel="alternate"/><published>2015-05-03T21:23:00+10:00</published><updated>2015-05-03T21:23:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2015-05-03:/porting-seeeduino-xadow-to-arduino-163.html</id><summary type="html">&lt;p&gt;&lt;a href="/media/0b8290_Xadow_Main_Board.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/0b8290_Xadow_Main_Board.jpg" data-border="0" width="200" height="150" /&gt;&lt;/a&gt;I bought a &lt;a href="http://www.seeedstudio.com/depot/Xadow-Main-Board-p-1524.html"&gt;Seeedstudio Xadow&lt;/a&gt; recently, and to get it to work with Arduino 1.6.3 was bit of a pain. Long story short, you can find the necessary files along with pithy instructions at my &lt;a href="https://github.com/freespace/Files_For_Seeed_Main_Board/tree/master/v1.6.3"&gt;github repo&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;The most crucial difference between the &lt;a href="https://github.com/Seeed-Studio/Files_For_Seeed_Main_Board"&gt;files Seeedstudio supplied&lt;/a&gt; and what …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/media/0b8290_Xadow_Main_Board.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/0b8290_Xadow_Main_Board.jpg" data-border="0" width="200" height="150" /&gt;&lt;/a&gt;I bought a &lt;a href="http://www.seeedstudio.com/depot/Xadow-Main-Board-p-1524.html"&gt;Seeedstudio Xadow&lt;/a&gt; recently, and to get it to work with Arduino 1.6.3 was bit of a pain. Long story short, you can find the necessary files along with pithy instructions at my &lt;a href="https://github.com/freespace/Files_For_Seeed_Main_Board/tree/master/v1.6.3"&gt;github repo&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;The most crucial difference between the &lt;a href="https://github.com/Seeed-Studio/Files_For_Seeed_Main_Board"&gt;files Seeedstudio supplied&lt;/a&gt; and what is needed is that when referencing the core and variant, you must specify the vendor ID, or Arduino 1.6.3 will assume that you have custom source files in the vendor directory. In other words, instead of  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;Xadow.core=arduino&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;You must write  &lt;/p&gt;
&lt;p&gt;&lt;code&gt;Xadow.core=arduino:arduino&lt;/code&gt;  &lt;/p&gt;
&lt;p&gt;This bit of information, along with others, is documented on &lt;a href="https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification"&gt;arduino's github wiki&lt;/a&gt;, in particular &lt;a href="https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification#referencing-another-core-variant-or-tool"&gt;Referencing another core, variant or tool&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="electronics"/><category term="arduino"/><category term="software"/><category term="seeeduino"/></entry><entry><title>Producing Technical Drawings In Blender</title><link href="/producing-technical-drawings-in-blender.html" rel="alternate"/><published>2014-12-04T15:29:00+11:00</published><updated>2014-12-04T15:29:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2014-12-04:/producing-technical-drawings-in-blender.html</id><summary type="html">&lt;p&gt;I do all my 3D design in Blender, producing models fit for 3D printing. It isn't as hard as it sounds as long as you keep to the following rules:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep consistent scale. For me that means 1 Blender unit = 1 mm&lt;/li&gt;
&lt;li&gt;Use boolean operations on meshes, avoid editing meshes …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;I do all my 3D design in Blender, producing models fit for 3D printing. It isn't as hard as it sounds as long as you keep to the following rules:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep consistent scale. For me that means 1 Blender unit = 1 mm&lt;/li&gt;
&lt;li&gt;Use boolean operations on meshes, avoid editing meshes directly&lt;/li&gt;
&lt;li&gt;This keeps things clean, modular, and most of all, ensures the resulting mesh is manifold, aka. watertight&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Select Non-Manifold&lt;/strong&gt; in edit mode to verify the correctness of the mode&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Recalculate Normals&lt;/strong&gt; before exporting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sometimes the model is a prototype, that needs to be manufactured by hand, technical drawings of a model is required, as illustrated by the following screenshot.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/ffd01d_blender_technical_render_tut_1.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/ffd01d_blender_technical_render_tut_1.png" data-border="0" width="640" height="380" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;Top is the model to be manufactured, bottom is a render of the model from the top in technical drawing style. In yellow are the necessary Free Style settings.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To achieve this look, you need to first set the camera to &lt;strong&gt;Orthographic&lt;/strong&gt; mode, then enable &lt;strong&gt;Freestyle&lt;/strong&gt; rendering in the render tab.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/7e499f_blender_technical_render_tut_3.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/7e499f_blender_technical_render_tut_3.png" data-border="0" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;In orthographic mode moving the camera towards or away from the object has no effect on its size. &lt;strong&gt;Orthographic Scale&lt;/strong&gt; is what you need to change to "zoom" in and out.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/8331c1_blender_technical_render_tut_2.png" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/8331c1_blender_technical_render_tut_2.png" data-border="0" width="92" height="320" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;Freestyle&lt;/strong&gt; rendering is needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Lastly, it is necessary to use a shadeless white material since we don't want lighting of any kind.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/764444_blender_technical_render_tut_4.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/764444_blender_technical_render_tut_4.png" data-border="0" width="156" height="400" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;A white shadeless material removes the need for lighting, and thus eliminates shading in the resulting render.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Internal Edges&lt;/h3&gt;
&lt;p&gt;It is possible to make internal edges, such as the edge of a channel, show up in the render. This is done by changing the &lt;strong&gt;Visibility&lt;/strong&gt; setting in the &lt;strong&gt;Freestyle Render Layer&lt;/strong&gt; settings.  &lt;/p&gt;
&lt;p&gt;When rendering internal edges, sometimes undesirable edges will show up. These can be convinced to go away by experimenting with the &lt;strong&gt;Edge Type&lt;/strong&gt; checkboxes.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/8e8bee_blender_technical_render_tut_5.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/8e8bee_blender_technical_render_tut_5.png" data-border="0" width="125" height="400" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;strong&gt;QI range&lt;/strong&gt; allows rendering of internal edges, while &lt;strong&gt;Edge Types&lt;/strong&gt; allows elimination of undesirable internal edges.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Examples&lt;/h3&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/08ead0_collagen_channel_phantom_A_front.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="/media/08ead0_collagen_channel_phantom_A_front.png" data-border="0" width="320" height="180" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/9dc4dc_collagen_channel_phantom_A_top.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="/media/9dc4dc_collagen_channel_phantom_A_top.png" data-border="0" width="320" height="180" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;h3&gt;Missing Features&lt;/h3&gt;
&lt;p&gt;Missing is the ability to add dimensions, that is something I haven't found a nice way of doing in blender, so for now it is added in post using Inkscape, or just by drawing on the printout.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="blender"/></entry><entry><title>Further Adventures in Python Optimisation</title><link href="/further-adventures-in-python-optimisation.html" rel="alternate"/><published>2014-09-12T15:55:00+10:00</published><updated>2014-09-12T15:55:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2014-09-12:/further-adventures-in-python-optimisation.html</id><summary type="html">&lt;p&gt;&lt;a href="http://blog.shuningbian.net/2014/09/adventures-in-python-optimisation.html"&gt;Previously&lt;/a&gt; we found that PyPy achieves the best performance gain, executing &lt;code&gt;fieldfunc_py&lt;/code&gt; in ~6 us. At the end of that article, I mentioned that the C implementation is up to 50x faster, managing the same calculation in ~0.12 us.&lt;/p&gt;
&lt;p&gt;The naive conclusion is that the best thing is to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://blog.shuningbian.net/2014/09/adventures-in-python-optimisation.html"&gt;Previously&lt;/a&gt; we found that PyPy achieves the best performance gain, executing &lt;code&gt;fieldfunc_py&lt;/code&gt; in ~6 us. At the end of that article, I mentioned that the C implementation is up to 50x faster, managing the same calculation in ~0.12 us.&lt;/p&gt;
&lt;p&gt;The naive conclusion is that the best thing is to simply call the C function to do the heavy lifting, achieving performance somewhere between PyPy and C. But nothing in life is easy...&lt;/p&gt;
&lt;h1&gt;Naive C Interfacing&lt;/h1&gt;
&lt;p&gt;The C code in the previous article was compiled using&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;gcc -O -shared -o c_fieldfunc.so -fPIC c_fieldfunc.c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;MagnetElement&lt;/code&gt; class was then amended to use the C function whenever possible:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MagnetElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fieldcalcfunc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot; &lt;/span&gt;
&lt;span class="s2"&gt;    position, and magnetisation are all expected to be numpy arrays of 3&lt;/span&gt;
&lt;span class="s2"&gt;    elements each.&lt;/span&gt;

&lt;span class="s2"&gt;    size is a single number, implying all elements are square&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fieldcalcfunc&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ctypes&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;cmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cdll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;c_fieldfunc.so&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cmodule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fieldAt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cfieldAt&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_cfieldAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ctypes&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_void_p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fieldAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot; &lt;/span&gt;
&lt;span class="s2"&gt;    p is expected to be a numpy array of 3&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This however yielded a per-run time of ~28 us!! So clearly there is significant cost in interfacing. The most obvious of these is creating a new &lt;code&gt;np.array&lt;/code&gt; each time, and defining and calling &lt;code&gt;voidp&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;A Better C Interface&lt;/h1&gt;
&lt;p&gt;Below is an improved version:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MagnetElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fieldcalcfunc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot; &lt;/span&gt;
&lt;span class="s2"&gt;    position, and magnetisation are all expected to be numpy arrays of 3&lt;/span&gt;
&lt;span class="s2"&gt;    elements each.&lt;/span&gt;

&lt;span class="s2"&gt;    size is a single number, implying all elements are square&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;magnetisation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fieldcalcfunc&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ctypes&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;cmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cdll&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadLibrary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;c_fieldfunc.so&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cmodule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fieldAt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cfieldAt&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_void_p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_position_p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_moment_p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_field_p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;voidp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_field&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OSError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;_cfieldAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ctypes&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_void_p&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctypes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_position_p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_moment_p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_field_p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_field&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fieldAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;    p is expected to be a numpy array of 3&lt;/span&gt;
&lt;span class="s2"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fieldcalcfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we are down to ~7 us, which is about what PyPy gave us. We are still slower, and more effort is involved compared to the installing PyPy + numpy. That said, this method has the advantage that it is compatible with existing Python and numpy installations, and can be used to optimise python code that uses parts of numpy that are not yet implemented in PyPy.&lt;/p&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;C interfacing needs to be done carefully to gain maximum benefit&lt;/li&gt;
&lt;li&gt;Not quite as easy as using PyPy, but more compatible&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Addendum&lt;/h1&gt;
&lt;p&gt;While we achieved performance similar to PyPy using C interfacing in this one function, PyPy is going to give faster performance across the entire program, while Python+C will only speed up this one function. In my particular case, Python+C is over all ~2x as slow as PyPy.&lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve  &lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="code"/><category term="software"/></entry><entry><title>Adventures in Python Optimisation</title><link href="/adventures-in-python-optimisation.html" rel="alternate"/><published>2014-09-12T14:41:00+10:00</published><updated>2014-09-12T14:41:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2014-09-12:/adventures-in-python-optimisation.html</id><summary type="html">&lt;p&gt;Recently I found myself looking at the following piece of code and trying to optimise it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;__future__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;division&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;MagneticPermeability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;1e-7&lt;/span&gt;
&lt;span class="n"&gt;MagneticPermeabilityOver4Pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MagneticPermeability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rmag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rdash3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rmag …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Recently I found myself looking at the following piece of code and trying to optimise it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;__future__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;division&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;MagneticPermeability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;1e-7&lt;/span&gt;
&lt;span class="n"&gt;MagneticPermeabilityOver4Pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MagneticPermeability&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rmag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rdash3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rmag&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rdash5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rmag&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rminus5term&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rdash5&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;rminus3term&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rdash3&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rminus5term&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rminus3term&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MagneticPermeabilityOver4Pi&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This, I have been told, computes the field at &lt;code&gt;p&lt;/code&gt; due to a magnetic di-pole at &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To profile this code I wrote the following function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;double&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;V&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# force the JIT or whatever to run&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;timeit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;per run&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;1e6&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;runs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;us&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This yields a per-run time of ~22 us.&lt;/p&gt;
&lt;h1&gt;Optimise Python/Numpy&lt;/h1&gt;
&lt;p&gt;The first optimisation then is to write a better optimised version:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;def fieldfunc_fast_py(p, q, moment):
  r = p - q
  rmag2 = np.dot(r, r)

  rdash3 = rmag2**1.5
  rdash5 = rmag2**2.5

  rminus5term = r &lt;span class="gs"&gt;* np.dot(moment, r) *&lt;/span&gt; 3 / rdash5
  rminus3term = moment / rdash3

  field = (rminus5term - rminus3term) * MagneticPermeabilityOver4Pi
  return field
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The main difference is using &lt;code&gt;np.dot()&lt;/code&gt; and avoiding &lt;code&gt;np.sqrt()&lt;/code&gt;. Using &lt;code&gt;**&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; faster than using square root and multiplication. These changes gets us down to ~18 us or so, so slight improvement.&lt;/p&gt;
&lt;h1&gt;numba&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://numba.pydata.org/"&gt;Numba&lt;/a&gt; offers JIT compilation of python into native code, and is pretty easy to use and compatible with numpy. To use it the profile function was called as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;profile(jit(fieldfunc_py))
profile(jit(fieldfunc_fast_py))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using &lt;code&gt;jit&lt;/code&gt; without type arguments causes numba to infer the type. This yields per-run time of ~22 us for &lt;code&gt;fieldfunc_py&lt;/code&gt; and ~18 us for &lt;code&gt;fieldfunc_fast_py&lt;/code&gt;. There is no noticable speed up, in fact per-run times increased slightly. This is possibly due to the fact that the code is already pretty well optimised, and the extra overhead of interfacing between compiled code and the python runtime.&lt;/p&gt;
&lt;h1&gt;PyPy&lt;/h1&gt;
&lt;p&gt;&lt;a href="http://pypy.org/"&gt;PyPy&lt;/a&gt; is an altnerative implementation of Python that also uses JIT, but does it for the entire program. It is a little harder to use because it needs its own version of numpy, which is only partially implemented. For our needs this will suffice.&lt;/p&gt;
&lt;p&gt;With PyPy, we see significant improvement. &lt;code&gt;fieldfunc_py&lt;/code&gt;'s per-run time went down to ~6 us, and &lt;code&gt;fieldfunc_fast_py&lt;/code&gt;'s per-run time went down to ~6 us also. This is a huge improvement.&lt;/p&gt;
&lt;h1&gt;Data Type Matters&lt;/h1&gt;
&lt;p&gt;The diligent reader may have noticed that &lt;code&gt;profile&lt;/code&gt; accepts &lt;code&gt;dtype&lt;/code&gt; as a keyword arguments. This was used to test the effects of using &lt;code&gt;np.float32&lt;/code&gt; vs &lt;code&gt;np.float64&lt;/code&gt;. The following code was written:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;With&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numba&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jit&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;==&amp;gt; Using numba jit&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This yielded the following output using CPython:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;With&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float32&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;30.8365797997&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;27.7728509903&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;numba&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;jit&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;22.2719597816&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;18.1778311729&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;

&lt;span class="nx"&gt;With&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float64&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;21.8909192085&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;17.5257897377&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;numba&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;jit&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;22.4718093872&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;18.2463383675&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Choice of data type has a significant effect, and it counter-intuitive: the larger data type is faster. Interestingly the same isn't true for PyPy, which outputted:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;With&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float32&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;6.29536867142&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;6.067070961&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;

&lt;span class="nx"&gt;With&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="nx"&gt;numpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;float64&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;6.28163099289&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;span class="nx"&gt;fieldfunc_fast_py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;per&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;6.17563962936&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;us&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which is essentially the same.&lt;/p&gt;
&lt;h1&gt;How Fast Can It Be Done?&lt;/h1&gt;
&lt;p&gt;The final question is, how fast can this be done? Here is a naive C implementation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;math.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vdot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Computes w=u+v&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vadd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Computes w=u-v&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Computes w = x*u, returns w&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vmult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#define MagneticPermeability          (4*M_PI*1e-7f)&lt;/span&gt;
&lt;span class="cp"&gt;#define MagneticPermeabilityOver4Pi   (MagneticPermeability/(4*M_PI))&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;vprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;(%e, %e, %e)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fieldfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rmag2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vdot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rdash3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rmag2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rdash5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rmag2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t5&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vmult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vdot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vmult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rdash5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vmult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rdash3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vmult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MagneticPermeabilityOver4Pi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;vprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;fieldfunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;timing was done as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;gcc&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;c_bench&lt;span class="w"&gt; &lt;/span&gt;c_bench.c&lt;span class="w"&gt; &lt;/span&gt;-lm&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;./c_bench&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.000000e+00,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.924501e-11,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.924501e-11&lt;span class="o"&gt;)&lt;/span&gt;

real&lt;span class="w"&gt;    &lt;/span&gt;0m0.116s
user&lt;span class="w"&gt;    &lt;/span&gt;0m0.114s
sys&lt;span class="w"&gt;     &lt;/span&gt;0m0.001s
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because we do 1 million iterations, per-run time is ~0.12 us, or around 50 times faster.&lt;/p&gt;
&lt;h1&gt;Summary&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Most gain/effort comes from using PyPy&lt;/li&gt;
&lt;li&gt;In this particular case, numba did not yield signficant speed up&lt;/li&gt;
&lt;li&gt;C is still much faster&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="c"/><category term="code"/><category term="software"/></entry><entry><title>Play Child of Light in English on PS Vita</title><link href="/play-child-of-light-in-english-on-ps-vita.html" rel="alternate"/><published>2014-08-30T00:01:00+10:00</published><updated>2014-08-30T00:01:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2014-08-30:/play-child-of-light-in-english-on-ps-vita.html</id><summary type="html">&lt;p&gt;If you want to play Child of Light on PS Vita, you will not only need to download the online update, you will also need to set your system language to English (US). If you have it set as English (UK) then you will continue seeing the game in Japanese …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you want to play Child of Light on PS Vita, you will not only need to download the online update, you will also need to set your system language to English (US). If you have it set as English (UK) then you will continue seeing the game in Japanese.&lt;/p&gt;
&lt;p&gt;I know right?&lt;/p&gt;</content><category term="posts"/></entry><entry><title>From Lyx/Latex to Word</title><link href="/from-lyxlatex-to-word.html" rel="alternate"/><published>2014-08-26T22:44:00+10:00</published><updated>2014-08-26T22:44:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2014-08-26:/from-lyxlatex-to-word.html</id><summary type="html">&lt;p&gt;This is sort of a placeholder post. Busy meeting a deadline, but this should help future Steve and anyone else when you need to turn your Lyx document into a Word document while keeping the format mostly sane. Broken, but sane.  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export as &lt;code&gt;Latex (plain)&lt;/code&gt;.  &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;latex &amp;lt;name of tex …&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;This is sort of a placeholder post. Busy meeting a deadline, but this should help future Steve and anyone else when you need to turn your Lyx document into a Word document while keeping the format mostly sane. Broken, but sane.  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Export as &lt;code&gt;Latex (plain)&lt;/code&gt;.  &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;latex &amp;lt;name of tex file, with or without extension&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bibtex &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;latex &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;latex &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Try to run&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;htlatex &amp;lt;filename&amp;gt; "html,0,charset=utf-8" "" -dhtml/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;html&lt;/code&gt;: format to output&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;: normally chapters go into their own page, putting 0 here forces everything into a single page&lt;/li&gt;
&lt;li&gt;&lt;code&gt;charset=utf-8&lt;/code&gt;: let us be civilised&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-dhtml/&lt;/code&gt;: puts the output files in a html sub-directory. Note that you can't have a space between &lt;code&gt;-d&lt;/code&gt; and the &lt;code&gt;html/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If the above fails with something like 'illegal storage address', and you get a warning about &lt;code&gt;text4ht.env&lt;/code&gt; not been found, then you need to find where it is in your TeX installation, and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;export TEX4HTENV&lt;/code&gt; and try again&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;text4ht.env&lt;/code&gt; into your working directory&lt;/li&gt;
&lt;li&gt;This approach also lets you affect locally some export parameters. More on this later...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the html to verify correctness. You might object to the poor graphics quality. In this case copy &lt;code&gt;text4ht.env&lt;/code&gt; into the working directory if you haven't done so, and then modify it so it uses a high density when converting images.  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;See this &lt;a href="http://tex.stackexchange.com/questions/43772/latex-xhtml-with-tex4ht-bad-quality-images-of-equations"&gt;tex.stackexchange.com&lt;/a&gt; answer for more details&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In my case, since dvipng was been used, I replaced all instances of&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D 96&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;with&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-D 300&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It also helps if you  &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;strip away html comments&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;These look like &lt;code&gt;&amp;lt;!-- xxx --&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;centre aligned image divs&lt;/li&gt;
&lt;li&gt;remove &lt;code&gt;&amp;lt;hr/&amp;gt;&lt;/code&gt; instances&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;These changes will make the import into Libre/OpenOffice go easier&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the html file in Libre/OpenOffice&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;File &amp;gt; Export &amp;gt; ODT&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Close html file&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open exported ODT&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Edit &amp;gt; Links&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Select all links&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Break Links&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify that the ODT file is now much larger!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;File &amp;gt; Save As &amp;gt; Word 97 (doc)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Phew! To help future visitors, a simple python script to fix up the html as I have described is included at the end of this post. You will need &lt;code&gt;lxml&lt;/code&gt; and &lt;code&gt;cssselector&lt;/code&gt; installed. Cheers, Steve&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;lxml.html&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlComment&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;lxml&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;etree&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="n"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getroot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cssselect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="c1"&gt;# replace &amp;lt;hr/&amp;gt; with &amp;lt;br/&amp;gt; to make doc conversion easier&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;hr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cssselect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hr&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getparent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;br&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;etree&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;br&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# remove comments because for some reason libreoffice opens up &lt;/span&gt;
  &lt;span class="c1"&gt;# html comments as document comments, slowing things down&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getiterator&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HtmlComment&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getparent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;# centre align all figures&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;div&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cssselect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;div.figure&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;div&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;attrib&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;style&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;text-align:center&amp;#39;&lt;/span&gt;

  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;etree&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tostring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
  &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="posts"/><category term="lyx"/><category term="code"/><category term="software"/><category term="latex"/></entry><entry><title>Reading Metadata Out of Nikon NIS Elements Generated TIFFs</title><link href="/reading-metadata-out-of-nikon-nis-elements-generated-tiffs.html" rel="alternate"/><published>2014-08-26T22:41:00+10:00</published><updated>2014-08-26T22:41:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2014-08-26:/reading-metadata-out-of-nikon-nis-elements-generated-tiffs.html</id><summary type="html">&lt;table class="tr-caption-container" data-cellpadding="0" data-cellspacing="0" style="float: right; margin-left: 1em; text-align: right;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/52135e_phantom_1_slice_A_cy5_1844.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/52135e_phantom_1_slice_A_cy5_1844.jpg" data-border="0" width="200" height="160" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;div style="text-align: left;"&gt;
&lt;span style="font-size: xx-small;"&gt;Fluorescence image of &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;cavitation effects,&lt;/span&gt;&lt;span style="font-size: xx-small;"&gt;visualised &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;using FITC-Dextran.&lt;/span&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If, like me, you use Nikon's NIS Elements to do fluorescence imaging, you would have also noticed that nothing other than NIS Elements can read the metadata that is saved with TIFFs. ImageJ can't read it, the GIMP can't read it, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;tiffinfo …&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;table class="tr-caption-container" data-cellpadding="0" data-cellspacing="0" style="float: right; margin-left: 1em; text-align: right;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/52135e_phantom_1_slice_A_cy5_1844.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img src="/media/52135e_phantom_1_slice_A_cy5_1844.jpg" data-border="0" width="200" height="160" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;&lt;div style="text-align: left;"&gt;
&lt;span style="font-size: xx-small;"&gt;Fluorescence image of &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;cavitation effects,&lt;/span&gt;&lt;span style="font-size: xx-small;"&gt;visualised &lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: xx-small;"&gt;using FITC-Dextran.&lt;/span&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;If, like me, you use Nikon's NIS Elements to do fluorescence imaging, you would have also noticed that nothing other than NIS Elements can read the metadata that is saved with TIFFs. ImageJ can't read it, the GIMP can't read it, &lt;span style="font-family: Courier New, Courier, monospace;"&gt;tiffinfo&lt;/span&gt; can't read it. This means the only way to recover that metadata, which contains important things like exposure time and pixel size is to open the image in NIS Elements.  &lt;/p&gt;
&lt;p&gt;This sucks, because NIS Elements isn't exactly easily or widely available, and NIS Elements Viewer doesn't help either - it only opens ND3 files.  &lt;/p&gt;
&lt;p&gt;Fret not, however. The metadata isn't encoded in any particularly nasty way, and with a little exploration I was able to put together &lt;a href="https://github.com/freespace/dphil-data-tools/blob/master/nikon-tiff-info.py"&gt;a small python script&lt;/a&gt; which will dump out all the relevant information.  &lt;/p&gt;
&lt;p&gt;Hope this helps someone. It would be nice if Nikon used the standard TIFF tags instead of putting everything in their own tags.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="code"/><category term="software patent"/><category term="oss"/></entry><entry><title>MYOB Not Printing Chinese Characters in Invoices</title><link href="/myob-not-printing-chinese-characters-in-invoices.html" rel="alternate"/><published>2013-11-06T12:10:00+11:00</published><updated>2013-11-06T12:10:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2013-11-06:/myob-not-printing-chinese-characters-in-invoices.html</id><content type="html">&lt;p&gt;Simply set the language for non-unicode programs to &lt;strong&gt;Chinese (PRC)&lt;/strong&gt; and it will magically work.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/b02360_myob_no_chinese_xp_fix.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="/media/b02360_myob_no_chinese_xp_fix.JPG" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;N.B. You must have first installed files for East Asia Languages in Languages Tab for this to work.&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="windows"/><category term="bugfix"/></entry><entry><title>Go Away AVN</title><link href="/go-away-avn.html" rel="alternate"/><published>2013-05-19T23:53:00+10:00</published><updated>2013-05-19T23:53:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2013-05-19:/go-away-avn.html</id><summary type="html">&lt;p&gt;So it turns out that if you &lt;a href="http://www.google.com.au/#sclient=psy-ab&amp;amp;q=vaccination&amp;amp;oq=vaccination&amp;amp;gs_l=hp.3..0l4.7363.7946.1.8094.6.1.0.5.5.0.78.78.1.1.0...0.0...1c.1.14.psy-ab._Ib24oa2G14&amp;amp;pbx=1&amp;amp;bav=on.2,or.r_qf.&amp;amp;bvm=bv.46751780,d.d2k&amp;amp;fp=48b675f837136d33&amp;amp;biw=1276&amp;amp;bih=668"&gt;google vaccination on google.com.au&lt;/a&gt;, &lt;a href="http://stopavn.com/"&gt;Australian Vaccination Network (AVN)&lt;/a&gt; comes up as the second result, right after wikipedia.  &lt;/p&gt;
&lt;table class="tr-caption-container" data-align="center" data-cellpadding="0" data-cellspacing="0" style="float: right; margin-left: 1em; text-align: right;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/eed3b0_vaccination_google_com_au.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnolUWTIRZKC1RcmaWCMvmCSoIL_cTMlKy7JCcz3sqPotxRNy3zj-B57R2pJHZQUqd5qFAVonltgvexohtxX62wboVnHJmqZztQZwDhS26VmnOrY8vi_FQ4AFybSfu3FgtnfU1KA/s200/vaccination_google_com_au.png" data-border="0" width="200" height="104" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;Search results from google.com.au for&lt;br /&gt;
"vaccination" as of 20th of May 2013&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As some of you may know, &lt;a href="http://stopavn.com/"&gt;AVN&lt;/a&gt; is an anti-vaccination …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So it turns out that if you &lt;a href="http://www.google.com.au/#sclient=psy-ab&amp;amp;q=vaccination&amp;amp;oq=vaccination&amp;amp;gs_l=hp.3..0l4.7363.7946.1.8094.6.1.0.5.5.0.78.78.1.1.0...0.0...1c.1.14.psy-ab._Ib24oa2G14&amp;amp;pbx=1&amp;amp;bav=on.2,or.r_qf.&amp;amp;bvm=bv.46751780,d.d2k&amp;amp;fp=48b675f837136d33&amp;amp;biw=1276&amp;amp;bih=668"&gt;google vaccination on google.com.au&lt;/a&gt;, &lt;a href="http://stopavn.com/"&gt;Australian Vaccination Network (AVN)&lt;/a&gt; comes up as the second result, right after wikipedia.  &lt;/p&gt;
&lt;table class="tr-caption-container" data-align="center" data-cellpadding="0" data-cellspacing="0" style="float: right; margin-left: 1em; text-align: right;"&gt;
&lt;colgroup&gt;
&lt;col style="width: 100%" /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/eed3b0_vaccination_google_com_au.png" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnolUWTIRZKC1RcmaWCMvmCSoIL_cTMlKy7JCcz3sqPotxRNy3zj-B57R2pJHZQUqd5qFAVonltgvexohtxX62wboVnHJmqZztQZwDhS26VmnOrY8vi_FQ4AFybSfu3FgtnfU1KA/s200/vaccination_google_com_au.png" data-border="0" width="200" height="104" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class="tr-caption" style="text-align: center;"&gt;Search results from google.com.au for&lt;br /&gt;
"vaccination" as of 20th of May 2013&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As some of you may know, &lt;a href="http://stopavn.com/"&gt;AVN&lt;/a&gt; is an anti-vaccination organisation, part of the &lt;a href="http://www.csicop.org/si/show/anti-vaccination_movement"&gt;anti-vaccination movement&lt;/a&gt;, whose core beliefs rests on &lt;a href="http://www.bmj.com/content/340/bmj.c696"&gt;a retracted paper&lt;/a&gt; published by a doctor who was &lt;a href="http://news.bbc.co.uk/1/hi/8695267.stm"&gt;struck off the UK medical register&lt;/a&gt; after been found guilty of unprofessional and unethical conduct.  &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.vaccination.org.au/"&gt;Vaccination&lt;/a&gt; is a corner stone of public health policy, and the only means of protection for the most vulnerable amongst us who are unable to receive vaccinations. Through &lt;a href="http://www.immunise.health.gov.au/"&gt;vaccination&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Smallpox"&gt;smallpox&lt;/a&gt; was eradicated in 1979, and no child was ever again killed or maimed by it.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Child_with_Smallpox_Bangladesh.jpg/230px-Child_with_Smallpox_Bangladesh.jpg" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Child_with_Smallpox_Bangladesh.jpg/230px-Child_with_Smallpox_Bangladesh.jpg" data-border="0" width="131" height="200" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;A child with smallpox&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Due to the efforts of groups like the &lt;a href="http://stopavn.com/"&gt;AVN&lt;/a&gt; however, there has been recent decline in the number of children receiving vaccinations against common childhood &lt;a href="https://en.wikipedia.org/wiki/Pertussis"&gt;whooping cough&lt;/a&gt;, leading &lt;a href="http://www.couriermail.com.au/news/sunday-mail/whooping-cough-is-reaching-epidemic-proportions-in-queensland/story-e6frep2f-1225948738821"&gt;an outbreak of whooping cough in Queensland&lt;/a&gt;, and sadly, &lt;a href="http://www.couriermail.com.au/news/sunday-mail/whooping-cough-is-reaching-epidemic-proportions-in-queensland/story-e6frep2f-1225948738821"&gt;the death of several infants&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;While the Australian Government is taken action against the AVN, the fact it has such a prominent position in Google's search results is undermining the overall effort. Thankfully this is something you and I can do something about, and that is what this blog post is for: part of an effort to increase the &lt;a href="http://en.wikipedia.org/wiki/PageRank"&gt;PageRank&lt;/a&gt; of legitimate sources of vaccination like  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.vaccination.org.au/"&gt;http://www.vaccination.org.au/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.immunise.health.gov.au/"&gt;http://www.immunise.health.gov.au/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have a blog, make a post like this one, &lt;a href="http://www.google.com.au/#sclient=psy-ab&amp;amp;q=vaccination&amp;amp;oq=vaccination&amp;amp;gs_l=hp.3..0l4.7363.7946.1.8094.6.1.0.5.5.0.78.78.1.1.0...0.0...1c.1.14.psy-ab._Ib24oa2G14&amp;amp;pbx=1&amp;amp;bav=on.2,or.r_qf.&amp;amp;bvm=bv.46751780,d.d2k&amp;amp;fp=48b675f837136d33&amp;amp;biw=1276&amp;amp;bih=668"&gt;google vaccination on google.com.au&lt;/a&gt; and click on every result that is NOT AVN.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/></entry><entry><title>Un/check all items in iTunes 11</title><link href="/uncheck-all-items-in-itunes-11.html" rel="alternate"/><published>2012-12-15T13:35:00+11:00</published><updated>2012-12-15T13:35:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2012-12-15:/uncheck-all-items-in-itunes-11.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/79343c_42_01_ARTS_COURTESY_MOTH.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjispgqAfxUyAEL2lW-4SP6WwflaGZcsU7wfTdSLguTKyJZ4CbnhOV6gT-TPVH8EBu82R_IfkNUW7Ae8aAlLRgCf8ZBn5lV3A8c-3kYBa_eXPonx9fwhyphenhyphen9VlepcIia3zoGzhFvONA/s200/42_01_ARTS_COURTESY_MOTH.jpg" data-border="0" width="200" height="200" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;&lt;span id="goog_656902549"&gt;&lt;/span&gt;&lt;span id="goog_656902550"&gt;&lt;/span&gt;&lt;br&gt;
I subscribe to &lt;a href="http://themoth.org/"&gt;The Moth&lt;/a&gt;, and had previously selected &lt;em&gt;all&lt;/em&gt; episodes to be sync'd to my iPhone. Recently I found myself short on space, so I wanted to tell iTunes 11 to stop doing that. Previously, it was a simple case of multiple selection in a list and uncheck, but …&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/79343c_42_01_ARTS_COURTESY_MOTH.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjispgqAfxUyAEL2lW-4SP6WwflaGZcsU7wfTdSLguTKyJZ4CbnhOV6gT-TPVH8EBu82R_IfkNUW7Ae8aAlLRgCf8ZBn5lV3A8c-3kYBa_eXPonx9fwhyphenhyphen9VlepcIia3zoGzhFvONA/s200/42_01_ARTS_COURTESY_MOTH.jpg" data-border="0" width="200" height="200" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;&lt;span id="goog_656902549"&gt;&lt;/span&gt;&lt;span id="goog_656902550"&gt;&lt;/span&gt;&lt;br&gt;
I subscribe to &lt;a href="http://themoth.org/"&gt;The Moth&lt;/a&gt;, and had previously selected &lt;em&gt;all&lt;/em&gt; episodes to be sync'd to my iPhone. Recently I found myself short on space, so I wanted to tell iTunes 11 to stop doing that. Previously, it was a simple case of multiple selection in a list and uncheck, but with iTunes 11, it looked like I was going to have to do it all by hand... for over 200 episodes!  &lt;/p&gt;
&lt;p&gt;By playing around, I found that if you &lt;strong&gt;&lt;span style="color: red;"&gt;command-click&lt;/span&gt;&lt;/strong&gt; on a checkbox, it has the effect of un/checking all the checkboxes in the list. This made things more manageable.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Unknown control sequence \doublespacing</title><link href="/unknown-control-sequence-doublespacing.html" rel="alternate"/><published>2012-10-16T17:23:00+11:00</published><updated>2012-10-16T17:23:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2012-10-16:/unknown-control-sequence-doublespacing.html</id><content type="html">&lt;p&gt;If you are getting the error  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;"Unknown control sequence: \doublespacing"&lt;/span&gt; when you try to compile your &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Beamer_(LaTeX)"&gt;beamer&lt;/a&gt; presentation in &lt;a href="http://www.lyx.org/"&gt;Lyx&lt;/a&gt;, change  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Document→Settings→Text Layout→Line spacing&lt;/strong&gt; &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;to &lt;strong&gt;Single&lt;/strong&gt;.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="lyx"/><category term="software"/><category term="oss"/></entry><entry><title>Downloads</title><link href="/downloads.html" rel="alternate"/><published>2012-09-15T14:36:00+10:00</published><updated>2012-09-15T14:36:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-09-15:/downloads.html</id><content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href="http://files.shuningbian.net/matrixSolver.zip"&gt;matrixSolver.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A matrix solver in C which can handle parametric solutions, i.e. singular matrices.&lt;/li&gt;
&lt;/ul&gt;</content><category term="posts"/></entry><entry><title>Notes On Running Calibre On A Server</title><link href="/notes-on-running-calibre-on-a-server.html" rel="alternate"/><published>2012-09-14T09:50:00+10:00</published><updated>2012-09-14T09:50:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-09-14:/notes-on-running-calibre-on-a-server.html</id><summary type="html">&lt;p&gt;&lt;a href="http://calibre-ebook.com/"&gt;Calibre&lt;/a&gt; is a great tool, especially for converting between ebook formats. Here are some notes for getting it to run on a headless server.  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The binary installer off the website works fine — ignore warnings about completion and desktop integration failing.&lt;/li&gt;
&lt;li&gt;The installer will always pollute &lt;span style="font-family: Courier New, Courier, monospace;"&gt;/usr/bin&lt;/span&gt; regardless of the …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://calibre-ebook.com/"&gt;Calibre&lt;/a&gt; is a great tool, especially for converting between ebook formats. Here are some notes for getting it to run on a headless server.  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The binary installer off the website works fine — ignore warnings about completion and desktop integration failing.&lt;/li&gt;
&lt;li&gt;The installer will always pollute &lt;span style="font-family: Courier New, Courier, monospace;"&gt;/usr/bin&lt;/span&gt; regardless of the installation directly you choose.&lt;/li&gt;
&lt;li&gt;You will need the following libraries for mobi conversion:&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;libxi6&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;libxrandr2&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;libxfixes3&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;libxcursor1&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;If you get this message&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;SVG rasterizer unavailable, SVG will not be converted&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;You will need to install &lt;span style="font-family: Courier New, Courier, monospace;"&gt;xvfb&lt;/span&gt; and use &lt;span style="font-family: Courier New, Courier, monospace;"&gt;xvfb-run&lt;/span&gt;, like so:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;xvfb-run ebook-convert blah.epub blah.mobi&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="oss"/><category term="linux"/></entry><entry><title>Nook vs Kindle</title><link href="/nook-vs-kindle.html" rel="alternate"/><published>2012-09-14T08:24:00+10:00</published><updated>2012-09-14T08:24:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-09-14:/nook-vs-kindle.html</id><summary type="html">&lt;p&gt;Definitely the Kindle. Amazon offers an amazing service, especially their personal document service's email feature. That is simply divine. Furthermore, Amazon isn't nearly so annoying to use as a non-US citizen. I don't have to use a trick credit card or proxies to purchase ebooks. Amazon just sells them to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Definitely the Kindle. Amazon offers an amazing service, especially their personal document service's email feature. That is simply divine. Furthermore, Amazon isn't nearly so annoying to use as a non-US citizen. I don't have to use a trick credit card or proxies to purchase ebooks. Amazon just sells them to me, easy peasy.  &lt;/p&gt;
&lt;p&gt;Disclaimer: I have a first generation Nook and a Kindle Touch. My comments above are however entirely based on the services provided, not the devices themselves. So this is probably more appropriate as Barnes and Noble vs Amazon.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/></entry><entry><title>Acorn vs Pixelmator</title><link href="/acorn-vs-pixelmator.html" rel="alternate"/><published>2012-09-14T08:20:00+10:00</published><updated>2012-09-14T08:20:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-09-14:/acorn-vs-pixelmator.html</id><content type="html">&lt;p&gt;&lt;a href="http://www.pixelmator.com/"&gt;Pixelmator&lt;/a&gt; wins hands down. Compared to Pixelmator &lt;a href="http://flyingmeat.com/acorn/"&gt;Acorn&lt;/a&gt; is anaemic in terms of features and costs more than twice as much.  &lt;/p&gt;
&lt;p&gt;Disclosure:  I originally got Acorn as part of MacHeist, so I didn't pay full price for it. I did pay full price for Pixelmator.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/><category term="software"/><category term="osx"/></entry><entry><title>Thoughts on The Design of SPOT2 GPS</title><link href="/thoughts-on-the-design-of-spot2-gps.html" rel="alternate"/><published>2012-08-28T08:35:00+10:00</published><updated>2012-08-28T08:35:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-08-28:/thoughts-on-the-design-of-spot2-gps.html</id><summary type="html">&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;

&lt;img src="/media/e7b582_images.jpeg" data-border="0" /&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;I love the fact the screws holding down the battery cover has little flip up handles so you can turn them with just your fingers, and that they are set so that they don't fall out once loosened. This is top quality design. However, the battery compartment door is not …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;

&lt;img src="/media/e7b582_images.jpeg" data-border="0" /&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;I love the fact the screws holding down the battery cover has little flip up handles so you can turn them with just your fingers, and that they are set so that they don't fall out once loosened. This is top quality design. However, the battery compartment door is not attached to the unit, and it should be, so there is no risk of losing that. Admittedly, it is pretty hard to lose something that is fairly large and orange&lt;/li&gt;
&lt;li&gt;Somewhat more importantly, the SOS button should be hooked into the power button, in the sense that if you press and hold the SOS button, it turns the device on and goes into SOS mode. As it is, activating SOS is a 2 step process, requiring you to first turn the device on.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;



&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/></entry><entry><title>Jumpcut is dead. Long live Jumpcut</title><link href="/jumpcut-is-dead-long-live-jumpcut.html" rel="alternate"/><published>2012-08-23T07:57:00+10:00</published><updated>2012-08-23T07:57:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-08-23:/jumpcut-is-dead-long-live-jumpcut.html</id><summary type="html">&lt;div class="separator" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"&gt;

&lt;img src="/media/bffcff_jumpcut.png" data-border="0" /&gt;

&lt;/div&gt;

&lt;p&gt;I used to use &lt;a href="http://jumpcut.sourceforge.net/"&gt;Jumpcut&lt;/a&gt; a long time ago, and was a big fan of it. At some point, I think around 10.5, it stopped working, and I let it go -- too busy at the time to poke at it.  &lt;/p&gt;
&lt;p&gt;Recently however my interest in it was piqued again …&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"&gt;

&lt;img src="/media/bffcff_jumpcut.png" data-border="0" /&gt;

&lt;/div&gt;

&lt;p&gt;I used to use &lt;a href="http://jumpcut.sourceforge.net/"&gt;Jumpcut&lt;/a&gt; a long time ago, and was a big fan of it. At some point, I think around 10.5, it stopped working, and I let it go -- too busy at the time to poke at it.  &lt;/p&gt;
&lt;p&gt;Recently however my interest in it was piqued again, and downloaded the &lt;a href="http://downloads.sourceforge.net/jumpcut/Jumpcut_0.63.tgz"&gt;0.63 source&lt;/a&gt;. To my great delight, it compiles just fine, and once recompiled, works perfectly. Score one for good programming and open source!  &lt;/p&gt;
&lt;p&gt;If like me you have given up on Jumpcut, it is time to add this nifty utility back to your toolbox.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve  &lt;/p&gt;
&lt;p&gt;P.S. If you don't have access to Xcode, or the idea of compiling a program sounds like a bit too much, drop me a line at freespace *at* gmail.com and I will make my copy available.&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="osx"/><category term="oss"/></entry><entry><title>Converting Excel 1.0 Files On OS X (or some other OS)</title><link href="/converting-excel-10-files-on-os-x-or-some-other-os.html" rel="alternate"/><published>2012-08-19T01:51:00+10:00</published><updated>2012-08-19T01:51:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-08-19:/converting-excel-10-files-on-os-x-or-some-other-os.html</id><summary type="html">&lt;ol&gt;
&lt;li&gt;Download &lt;a href="http://sheepshaver.cebix.net/#download"&gt;SheepShaver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download "New World PPC ROM" from &lt;a href="http://www.redundantrobot.com/sheepshaver-tutorial/"&gt;redundantrobot.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Extract the zip. This should produce &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;newworld86.rom&lt;/strong&gt;&lt;/span&gt;. Rename this file to &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;ROM&lt;/strong&gt;&lt;/span&gt; and put it in the same directory as SheepShaver.app&lt;/li&gt;
&lt;li&gt;At this point SheepShaver.app should run, showing you a folder with a blinking ? inside it&lt;/li&gt;
&lt;li&gt;Download …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;ol&gt;
&lt;li&gt;Download &lt;a href="http://sheepshaver.cebix.net/#download"&gt;SheepShaver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Download "New World PPC ROM" from &lt;a href="http://www.redundantrobot.com/sheepshaver-tutorial/"&gt;redundantrobot.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Extract the zip. This should produce &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;newworld86.rom&lt;/strong&gt;&lt;/span&gt;. Rename this file to &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;ROM&lt;/strong&gt;&lt;/span&gt; and put it in the same directory as SheepShaver.app&lt;/li&gt;
&lt;li&gt;At this point SheepShaver.app should run, showing you a folder with a blinking ? inside it&lt;/li&gt;
&lt;li&gt;Download "Mac OS 9 Boot Image (120 megs)", again from &lt;a href="http://www.redundantrobot.com/sheepshaver-tutorial/"&gt;redundantrobot.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unzip the downloaded file. This should produce &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;OS9.img&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Access SheepShaver's Preferences, and add &lt;strong&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;OS9.img&lt;/span&gt;&lt;/strong&gt; to Volumes. Hit Save and restart SheepShaver&lt;/li&gt;
&lt;li&gt;SheepShaver should now boot into OS9. Ignore the warning about virtual memory&lt;/li&gt;
&lt;li&gt;On the desktop, there should be a Unix drive. This is your Mac's system volume. All your files can be accessed through this.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="http://macintoshgarden.org/apps/microsoft-excel"&gt;Excel for Mac archive&lt;/a&gt; from &lt;a href="http://macintoshgarden.org/"&gt;Macintosh Garden&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unzip, this should produce &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;Microsoft Excel&lt;/strong&gt;&lt;/span&gt; folder, inside you will find 5 versions of Excel&lt;/li&gt;
&lt;li&gt;Navigate to this folder OS9, and enter &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;Excel 4.0 Folder&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;Run Excel, and navigate to your Excel 1.0 files.&lt;/li&gt;
&lt;li&gt;Open each file, then save it again using &lt;span style="font-family: Courier New, Courier, monospace;"&gt;&lt;strong&gt;Normal Format&lt;/strong&gt;&lt;/span&gt; which is just Excel 3.0. Probably a good idea to add &lt;strong&gt;&lt;span style="font-family: Courier New, Courier, monospace;"&gt;xls&lt;/span&gt;&lt;/strong&gt; to avoid overwriting the original.&lt;/li&gt;
&lt;li&gt;Open the converted Excel 3.0 file in modern Excel. Microsoft Excel for Mac 2011 is capable of opening Excel 3.0 files.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;

At step 14 you might run into a problem I faced: Excel simply won't see any of the Excel 1.0 files! The problem is that Excel is using extended file attributes to determine which files it can open. On less sophisticated systems this is done via file extensions.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

To see this, if you copy **&lt;span style="font-family: Courier New, Courier, monospace;"&gt;COMMANDS&lt;/span&gt;** file out of Excel 1.03's sample directory (you have to convert the image first using Disk Utility), and run &lt;span style="font-family: Courier New, Courier, monospace;"&gt;**xattr**&lt;/span&gt; on it, you will see this:

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**\$ xattr COMMANDS **&lt;/span&gt;

&lt;/div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**com.apple.FinderInfo**&lt;/span&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

Content of &lt;span style="font-family: Courier New, Courier, monospace;"&gt;**com.apple.FinderInfo**&lt;/span&gt; is:

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**\$ xattr -px com.apple.FinderInfo COMMANDS**&lt;/span&gt;

&lt;/div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**58 4C 50 47 58 43 45 4C 01 00 00 00 00 00 00 00**&lt;/span&gt;

&lt;/div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00**&lt;/span&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

This is the magic you need. Suppose you had a Excel 1.0 file called &lt;span style="font-family: Courier New, Courier, monospace;"&gt;**foo**&lt;/span&gt;, you add this extended file attribute as follows:

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

&lt;span style="font-family: Courier New, Courier, monospace;"&gt;**\$ xattr -wx com.apple.FinderInfo "\$(xattr -px com.apple.FinderInfo COMMANDS)" foo**&lt;/span&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

After doing this foo should show up in Excel inside ShavedSheep.

&lt;/div&gt;

&lt;div&gt;


If all this sounds like too much for you, send me an email at freespace \_at\_ gmail.com with subject of "Excel 1.0 Conversion".  

**Update**  

An alternative to using Sheep Shaver and OS 9 is to use Mini vMac and System 6. This will let you run Excel 1.0.  

1.  [Download Mini vMac](http://minivmac.sourceforge.net/doc/download.html)
2.  Download "Mac Classic ROM" from [redundantrobot.com](http://www.redundantrobot.com/sheepshaver-tutorial/). Extracting the zip produces **&lt;span style="font-family: Courier New, Courier, monospace;"&gt;vmac.rom&lt;/span&gt;** which is incidentally the exact filename Mini vMac expects
3.  Follow [these instructions](http://minivmac.sourceforge.net/doc/start.html) to get System 6.0.8 running
4.  Drag-n-drop the Excel 1.0 program **&lt;span style="font-family: Courier New, Courier, monospace;"&gt;img&lt;/span&gt;** file (see above) directly into Mini vMac. You will now have access to Excel 1.0
5.  To get a read/writable disk, create a **&lt;span style="font-family: Courier New, Courier, monospace;"&gt;dmg&lt;/span&gt;** in Disk Utility. Drag-n-drop this into Mini vMac and you will be asked to initalize and format it. Do so, and then drag-n-drop Excel into this new read-writable disk.
6.  Do your conversion, shutdown Mini vMac
7.  Open the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;**dmg**&lt;/span&gt;, and it should mount, despite having been initalized and formatted by System 6.0.8 -- backward compatibility for the win

&lt;div&gt;

Mini vMac is not as powerful as Sheep Shaver, and System 6.0.8 is as much as it can handle. It is however much smaller and easier to use than Sheep Shaver, and for the purpose of converting Excel 1.0 to a more manageable format is more than sufficient.  

Note that you might need to do the **&lt;span style="font-family: Courier New, Courier, monospace;"&gt;xattr&lt;/span&gt;** trick above.

&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="computer"/></entry><entry><title>A Layman's Incomplete and Probably Inaccurate Understanding of The GFC</title><link href="/a-laymans-incomplete-and-probably-inaccurate-understanding-of-the-gfc.html" rel="alternate"/><published>2012-08-15T11:54:00+10:00</published><updated>2012-08-15T11:54:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-08-15:/a-laymans-incomplete-and-probably-inaccurate-understanding-of-the-gfc.html</id><summary type="html">&lt;p&gt;&lt;strong&gt;&lt;em&gt;Foreword:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;It has been four years or so since the world went through the throes of financial upheaval known as the Great Financial Crisis. It was a complex event that will not doubt be analysed in depth by experts for years, if not centuries to come, as an example of …&lt;/em&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;&lt;em&gt;Foreword:&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;It has been four years or so since the world went through the throes of financial upheaval known as the Great Financial Crisis. It was a complex event that will not doubt be analysed in depth by experts for years, if not centuries to come, as an example of what could happen. Sometimes we forget that we are still part of a grand experiment, and that nothing like our civilisation has ever existed before. This means that some lessons must be learnt the hard way. The recent LIBOR scandal however would suggests that the financiers are slow learners...&lt;/em&gt;&lt;br&gt;
&lt;em&gt;*
&lt;/em&gt;This is blog posts crystallises my thoughts and understanding of the event, gleaned from various places over the last few years. I make no claims on accuracy or veracity -- it is labelled rant after all.&lt;em&gt;&lt;br&gt;
&lt;/em&gt;*
&lt;em&gt;Lastly, the terms I use below are only loosely connected to their actual meaning in the finance world. For example I use capital just so I can not use the word "money" so much. They mean the same thing here. And money just means something you can pay your debtors with.&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;Lets begin with some axioms:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is a ceiling to the amount of money a bank can loan out&lt;/li&gt;
&lt;li&gt;Therefore banks want to... realise the value of their loans as quickly as possible&lt;/li&gt;
&lt;li&gt;They are therefore willing to sell some loans at a discount, in order to free up money which they can loan to someone else, so they can make more money&lt;/li&gt;
&lt;li&gt;Perception of low interest rate is absolute, no relative. Thus if banks can borrow money at 1%, they can double the interest on their loans, i.e. 2%, and the perception of low interest rate is maintained. Whereas if the inter-bank loan rate was say, 20%, they can hardly add another percent without significantly affecting the number of people taking out loans.&lt;/li&gt;
&lt;li&gt;If the profit banks make, derived from the difference between the interest rate at which they borrow money, and the interest rate at which they loan money, is high enough, then it is profitable to take on high risk loans. The increased risk of default is balanced by the greater reward.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;

Now for the play:

&lt;/div&gt;

&lt;div&gt;

- Easy credit meant more people are eligible to take out loans, most of which were used to buy houses
  - As a result, housing prices went up, and size of loans increased as a result
  - Some branches are opportunistic, and under-rated the risk of loan applicants so they can give them loans.
- Banks started packaging high risk loans, which they were giving out due to the high profit margin, with low risk loans, and selling the entire package as low risk.
  - For example, suppose risk is 0..1, where 0 means the loan will definitely be paid back, and 1 means instant default. If one packages nine risk=0.1 loans with a single risk=0.5 loan, then the overall package was being sold with risk=0.14.
  - This practice inflates enormously the value of high risk loans, at the relatively small expense of low risk loans. 
- These packages were then further manipulated. e.g. taken apart and with individual loans sold at the risk rating of the overall package. This serves to obscure the high risk nature of some of the loans in the package. 
  - For example, company A sells company B the above loans as a single package with risk=0.14. Company B then splits the package into five smaller portions, each with risk=0.14, and sells it to company C. If company C is lucky, it will be getting a good deal: two risk=0.1 loans instead of two risk=0.14 loans. If company C is unlucky, it will end up holding a risk=0.1 and a risk=0.5 loan.
  - These manipulation happened many times, to the point no one can be sure any longer of the true value of any individual loan.

&lt;div&gt;

Something happened at this point, I am not entirely clear what, but the effect was that financiers realised that some of the loans they hold are not worth what they are paid, so...

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;

- They raised interests rates to compensate for the suddenly higher risk of the loans they are holding, and;
- They tried to sell off those loans who providence cannot be verified.
- These had the effect of:
  - Increasing the number of defaults, and thus repossessions. As loan holders sold off houses in an attempt to recoup their costs, over-supply of houses depressed the price of houses, bursting the real estate bubble.
    - This meant that loan holders could not recoup their costs, and is thus operating at a loss
  - Devaluing the worth of loans with questionable providence, even if they are in fact low risk, and thus good loans.
    - This meant that loan holders were "stuck" with their loans
- Both of these combined meant that:
  - Loans were worth a fraction of what they were worth before
  - Loans could not be converted into liquid capital

&lt;div&gt;

This freezing of capital, and the devaluing of assets lead to panic in the financial world:

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;

- Creditors called in their debts, especially from those debtors who specialise in mortages
- But as mentioned above, the debtor's can't pay: the loans they have purchased with the money they had borrowed could not be converted back into capital.
  - As a result, debtors, often large financial institutions, go bankrupt or require injection of capital, i.e. "bail out"
- Over all effect: 
  - The collapse of major financial institutions
  - Erosion of trust in the financial systems
  - Devaluation of real estate
  - Increased homelessness as homes are repossessed
  - Increased unemployment as institutions closed
  - Slow down in the flow of credit as creditors become more reluctant to give out loans -- once bitten; twice shy.
  - Extreme devaluation in the assets and worth of investors, from banks to companies 

&lt;div&gt;

These effects were not just limited to the U.S. The inter-connected nature of modern financial markets meant that banks and institutions all over the world lost billions if not trillions of dollars in worth, and the reduction in available credit pushed up the interests rates.

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

More importantly, this was not limited to private companies. Many banks are owned nationally, and thus governments around the world suffer in much the same way as private enterprises:

&lt;/div&gt;

&lt;div&gt;

- Large part of their worth disappeared
- Higher interests rates
- Creditors calling in their debts

&lt;div&gt;

Governments also have to contend with:

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;

- Lower tax revenue
- Cost of bailouts to maintain social structure

&lt;div&gt;



&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/></entry><entry><title>2012-07-22</title><link href="/2012-07-22.html" rel="alternate"/><published>2012-07-22T13:09:00+10:00</published><updated>2012-07-22T13:09:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-07-22:/2012-07-22.html</id><summary type="html">&lt;p&gt;Over this weekend I have been working on faerii, a USB controlled RGB LED based around the ATtiny85.  &lt;/p&gt;
&lt;p&gt;Here is a picture of the breadboard prototype  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/241331_faerii_breadboard.jpg" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQqsHhMUEm5UOx_NGrx3d9aeP3WqHBVyy_yD2b1vHmzifD6z7tkZbxVxc_ukEMjxGEVDgNWnvruOgK_DnJi_jI7SB7sa6aaSvWE4juidF26-lv54RxRefFZkgKJh0KZGr_DmTWmw/s320/faerii_breadboard.jpg" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;faerii breadboard prototype&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;

The ATtiny85 is mid centre, and immediately above it is the ISP header. To the left of the ISP header, near …&lt;/div&gt;</summary><content type="html">&lt;p&gt;Over this weekend I have been working on faerii, a USB controlled RGB LED based around the ATtiny85.  &lt;/p&gt;
&lt;p&gt;Here is a picture of the breadboard prototype  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/241331_faerii_breadboard.jpg" style="margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQqsHhMUEm5UOx_NGrx3d9aeP3WqHBVyy_yD2b1vHmzifD6z7tkZbxVxc_ukEMjxGEVDgNWnvruOgK_DnJi_jI7SB7sa6aaSvWE4juidF26-lv54RxRefFZkgKJh0KZGr_DmTWmw/s320/faerii_breadboard.jpg" data-border="0" width="320" height="240" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;faerii breadboard prototype&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;

The ATtiny85 is mid centre, and immediately above it is the ISP header. To the left of the ISP header, near the centre, is a 4 pin header that provides USB connectivity. Obscuring it is two filter capacitors, pull resistors, and zener diodes. Finally on the far left edge is a common-anode RGB LED.

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;



&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;

Here is a video of it in operation:

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;



&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;

&lt;/div&gt;

&lt;div style="text-align: center;"&gt;



&lt;/div&gt;

&lt;div style="text-align: center;"&gt;

&lt;/div&gt;

&lt;div style="text-align: center;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

The project is based around the hid-data example from [vusb](http://www.obdev.at/products/vusb/index.html). The EEPROM contains control blocks, consisting of 4 bytes. The first 3 bytes specify the red, green and blue intensities, in that order. The last byte specifies a duration. Upon reading a control block, the LED transitions, over the specified duration, from its current colour to the new colour. Currently the duration specified in multiples of 20ms.

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

Lists of control blocks, which I call a control sequence, can be delimited using delimiter blocks. These blocks have a specified duration value of 0xff. When such a block is encountered, the sequence is restarted  from the beginning. Multiple sequences can be programmed into EEPROM.

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

The host software performs the job of programming sequences into EEPROM. It also provides additional commands, such as RESET and GOTO. The latter allows a collection of sequences to be stored in EEPROM, and activated individually. This feature was provided to minimise the amount of EEPROM writes required to change patterns. For example, sequences might be stored for an idle and new mail state. Activation then simply requires sending the correct GOTO command, without rewriting the EEPROM which as a limited write/erase cycle.

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

Currently a total of 62 control blocks can be stored. This is due to incomplete support for writing to arbitrary EEPROM address, and the fact the first block is reserved. It should be no great difficulty to fix this.

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

Two major features I have no implemented yet are REVERSE and MODIFY-ON-READ. These are animation options, where REVERSE specifies that upon reaching the end of a sequence, instead of starting again from the beginning, control blocks should be read backwards. MODIFY-ON-READ is more interesting. The intention is that after reading and executing a control block, the block's RGB  values should be modified. This allows free-running random colour cycling without explicit programming.

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

The [firmware and commandline utility source code is hosted at github](https://github.com/freespace/faerii). I will add proper schematics next weekend, though you can probably figure most of it by googling and looking at the photo above.

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="electronics"/></entry><entry><title>Notes on x86 Opcodes</title><link href="/notes-on-x86-opcodes.html" rel="alternate"/><published>2012-07-21T01:47:00+10:00</published><updated>2012-07-21T01:47:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-07-21:/notes-on-x86-opcodes.html</id><summary type="html">&lt;p&gt;Here are some notes I made while trying to understand the opcodes in &lt;a href="http://www.muppetlabs.com/%7Ebreadbox/software/tiny/teensy.html"&gt;this fun article on generating small elf binaries&lt;/a&gt;. Hopefully they will be of use.&lt;br&gt;
&lt;span class="Apple-style-span" style="color: #101000;"&gt;&lt;/span&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  00000000 B801000000        mov        eax, 1
  00000005 BB2A000000        mov        ebx, 42
  0000000A CD80              int        0x80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above snippet:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;B8 is the move instruction …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;Here are some notes I made while trying to understand the opcodes in &lt;a href="http://www.muppetlabs.com/%7Ebreadbox/software/tiny/teensy.html"&gt;this fun article on generating small elf binaries&lt;/a&gt;. Hopefully they will be of use.&lt;br&gt;
&lt;span class="Apple-style-span" style="color: #101000;"&gt;&lt;/span&gt;  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  00000000 B801000000        mov        eax, 1
  00000005 BB2A000000        mov        ebx, 42
  0000000A CD80              int        0x80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above snippet:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;B8 is the move instruction, in which the destination register is encoded into the opcode itself. The mov instruction is B8+r where r = 0..7, 0 being al/ax/eax depending on the data size. &lt;/li&gt;
&lt;li&gt;One might naively expect then that the next opcode to move 42 into ebx would be B9, and one would be wrong. The registers are not numbered alphabetically. The next 2 registers in sequence is cl/cx/ecx for r=1 and dl/dx/edx for r=2, and finally we get to bl/bx/ebx for r=3. This explains why the next mov instruction has value BB.&lt;ul&gt;
&lt;li&gt;Note also the little endian encoding of bytes in the operand.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  00000000 31C0              xor        eax, eax
  00000002 40                inc        eax
  00000003 B32A              mov        bl, 42
  00000005 CD80              int        0x80
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;div style="color: #101000;"&gt;

In the above snippet:

&lt;/div&gt;

- &lt;span class="Apple-style-span" style="color: #101000;"&gt;31 encodes xor&lt;/span&gt;
  - &lt;span class="Apple-style-span" style="color: #101000;"&gt;C0 is the [MOD-REG-R/M](http://www.c-jump.com/CIS77/CPU/x86/lecture.html#X77_0060_mod_reg_r_m_byte) byte, which has the format:&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;0..2: R/M (register or memory, 0..7)&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;3..5: REG (register, 0..7)&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;6..7: MOD (addressing mode, 0..4)&lt;/span&gt;
  - &lt;span class="Apple-style-span" style="color: #101000;"&gt;In this case, we have:&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;MOD=11&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;REG=0&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;R/M=0&lt;/span&gt;
    - &lt;span class="Apple-style-span" style="color: #101000;"&gt;Which says: addressing mode is register addressing mode, and the destination and source registers are eax (REG=0) and eax (R/M=0).&lt;/span&gt;
- &lt;span class="Apple-style-span" style="color: #101000;"&gt;40 is an instruction like B8, where the register to modify is encoded in the opcode itself. &lt;/span&gt;
- &lt;span class="Apple-style-span" style="color: #101000;"&gt;B3 is B0+r with r=3. This is like B8+r except B8+r deals with 16/32bit data while B0+r deals with 8bit data.&lt;/span&gt;
  - &lt;span class="Apple-style-span" style="color: #101000;"&gt;Recall again that the bl/bx/ebx is the 4th register, not the second.&lt;/span&gt;

&lt;div&gt;

&lt;span class="Apple-style-span" style="color: #101000;"&gt;Instruction information was sourced from the very useful [X86 Opcode and Instruction Reference](http://ref.x86asm.net/coder32.html).&lt;/span&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="asm"/><category term="software"/></entry><entry><title>GNU readline with System Python (OS X 10.7)</title><link href="/gnu-readline-with-system-python-os-x-107.html" rel="alternate"/><published>2012-07-21T01:46:00+10:00</published><updated>2012-07-21T01:46:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-07-21:/gnu-readline-with-system-python-os-x-107.html</id><summary type="html">&lt;p&gt;By default system python loads "fake" readline (fake because it actually uses &lt;a href="http://www.cs.utah.edu/~bigler/code/libedit.html"&gt;libedit&lt;/a&gt;) from &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/readline.so&lt;/span&gt;. Even if you install readline (which goes into &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/Library/Python/2.7/site-packages&lt;/span&gt;), it will still load it, even if you fiddle …&lt;/p&gt;</summary><content type="html">&lt;p&gt;By default system python loads "fake" readline (fake because it actually uses &lt;a href="http://www.cs.utah.edu/~bigler/code/libedit.html"&gt;libedit&lt;/a&gt;) from &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/readline.so&lt;/span&gt;. Even if you install readline (which goes into &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/Library/Python/2.7/site-packages&lt;/span&gt;), it will still load it, even if you fiddle with &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sys.path&lt;/span&gt;.  &lt;/p&gt;
&lt;p&gt;The one solution I have found, which I am not terribly proud of, is to rename &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;readline.so&lt;/span&gt; to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;readline.so.bak&lt;/span&gt;. This forces the GNU readline installed via &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pip/easy_install&lt;/span&gt; to be loaded.  &lt;/p&gt;
&lt;p&gt;Now I have nice things in the python interpreter again.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="software"/><category term="osx"/></entry><entry><title>DFT and the Window Spectrum</title><link href="/dft-and-the-window-spectrum.html" rel="alternate"/><published>2012-05-17T12:11:00+10:00</published><updated>2012-05-17T12:11:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-05-17:/dft-and-the-window-spectrum.html</id><summary type="html">&lt;p&gt;In case I forget again why the window spectrum is computed when doing DFT, the answer is that discretisation  leads to aliasing artefacts.  &lt;/p&gt;
&lt;p&gt;Consider the DFT of a x(t)=1. Its DFT is calculated by calculating the sum sin(2 pi f t)*x(t) and cos(2 pi …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In case I forget again why the window spectrum is computed when doing DFT, the answer is that discretisation  leads to aliasing artefacts.  &lt;/p&gt;
&lt;p&gt;Consider the DFT of a x(t)=1. Its DFT is calculated by calculating the sum sin(2 pi f t)*x(t) and cos(2 pi f t)*x(t) individually, then squaring the resulting sums, add them together, then  take the square root. Since x(t) = 1, for any frequency you are essentially summing cos(t) and sin(t), which you expect to be zero, and thus the power spectrum should be 0 for any frequency.  &lt;/p&gt;
&lt;p&gt;If you actually do this with, you will find that unless the points in time where sampling occurs covers an integer number of wavelengths, and is coherent in phase, i.e. sampling occurs in the same phase of each cycle, you will find that you don't get 0. You might get 0.1, 0.15, 0.09, 0.01, etc, but not 0. This is made more obvious by non-uniformely sampled data, such as those you might get in the real world.  &lt;/p&gt;
&lt;p&gt;This present a problem: the residue can produces peaks where there would otherwise be none, and this is more pronounced for lower frequency, because their wavelengths are longer and thus less likely to fit perfectly inside the window.  &lt;/p&gt;
&lt;p&gt;One way of rectifying this issue is to compute a correction coefficient c(f)=1-w(f) where f is the frequency, w(f) the window spectrum. The "corrected" power spectrum can then be calculated as correctp(f) = p(f) * c(f), where p(f) is the power spectrum.  &lt;/p&gt;
&lt;p&gt;I should add that the above method is not at all mathematical. It is chosen because any correction strategy that involves dividing by w(f) is unstable as sometimes w(f) gets very close to 0. Simply subtracting w(f) from p(f) won't work either because p(f)'s magnitude clearly depends on x(t) whereas  w(f) doesn't.  &lt;/p&gt;
&lt;p&gt;An obvious failure of the above correction is that it doesn't make the residue disappear - it only reduces it. A superior method would correct the DFT for a DC signal so it is 0 everywhere.  &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;  &lt;/p&gt;
&lt;p&gt;The obvious answer is to simply normalise x(t) so the maximum amplitude is 1.0. Then the window power can simply be subtracted. Duh.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="badmaths"/><category term="science"/></entry><entry><title>PSA: Using Lyx With Native OS X Spellchecker</title><link href="/psa-using-lyx-with-native-os-x-spellchecker.html" rel="alternate"/><published>2012-04-28T11:48:00+10:00</published><updated>2012-04-28T11:48:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-04-28:/psa-using-lyx-with-native-os-x-spellchecker.html</id><summary type="html">&lt;p&gt;Lyx 2.0 and onwards on OS X will use spellchecker provided by the OS X. Note however that the language it will use for spellchecking is determined by the document's language setting, not your system language setting.  &lt;/p&gt;
&lt;p&gt;Furthermore, in version 2.0.3, if you change your document's language …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Lyx 2.0 and onwards on OS X will use spellchecker provided by the OS X. Note however that the language it will use for spellchecking is determined by the document's language setting, not your system language setting.  &lt;/p&gt;
&lt;p&gt;Furthermore, in version 2.0.3, if you change your document's language setting, you have to close and re-open the document before it takes effect.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="lyx"/><category term="software"/><category term="oss"/><category term="PSA"/></entry><entry><title>Notes on RF-0417C</title><link href="/notes-on-rf-0417c.html" rel="alternate"/><published>2012-04-23T12:13:00+10:00</published><updated>2012-04-23T12:13:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2012-04-23:/notes-on-rf-0417c.html</id><summary type="html">&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;

&lt;img src="/media/d97332_BT0417C.gif" data-border="0" width="200" height="195" /&gt;

&lt;/div&gt;

&lt;p&gt;Some notes on using the popular Bluetooth serial module &lt;a href="http://www.mdfly.com/index.php?main_page=product_info&amp;amp;products_id=63"&gt;RF-0417C&lt;/a&gt;:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When sending AT commands, do not include &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;\r\n&lt;/span&gt; either together or singly.&lt;/li&gt;
&lt;li&gt;It appears to be happy to receive 5V inputs to TX.&lt;/li&gt;
&lt;li&gt;It is &lt;em&gt;not&lt;/em&gt; happy to receive 5V to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Vcc&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;If you connect a LED, it blinks …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;div style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;

&lt;img src="/media/d97332_BT0417C.gif" data-border="0" width="200" height="195" /&gt;

&lt;/div&gt;

&lt;p&gt;Some notes on using the popular Bluetooth serial module &lt;a href="http://www.mdfly.com/index.php?main_page=product_info&amp;amp;products_id=63"&gt;RF-0417C&lt;/a&gt;:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When sending AT commands, do not include &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;\r\n&lt;/span&gt; either together or singly.&lt;/li&gt;
&lt;li&gt;It appears to be happy to receive 5V inputs to TX.&lt;/li&gt;
&lt;li&gt;It is &lt;em&gt;not&lt;/em&gt; happy to receive 5V to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Vcc&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;If you connect a LED, it blinks when unpaired, blinks slightly faster when paired, and becomes solid when a serial connection is established.&lt;/li&gt;
&lt;li&gt;It works just fine with the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;a href="http://arduino.cc/en/Reference/SoftwareSerial"&gt;SoftwareSerial&lt;/a&gt;&lt;/span&gt; library.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="electronics"/><category term="arduino"/><category term="diy"/></entry><entry><title>PSA: Replacing the SuperDrive With A Hard Disk</title><link href="/psa-replacing-the-superdrive-with-a-hard-disk.html" rel="alternate"/><published>2012-02-12T13:41:00+11:00</published><updated>2012-02-12T13:41:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2012-02-12:/psa-replacing-the-superdrive-with-a-hard-disk.html</id><summary type="html">&lt;p&gt;Replacing the SuperDrive with a hard disk seems to be a Bad Idea at least in my 13" mid-2010 MBP: my 320GB WD Scorpio Blue took over a minute to copy 60MB. That is so 80s.  &lt;/p&gt;
&lt;p&gt;Interestingly, when I put the hard drive back to where it belongs, and put …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Replacing the SuperDrive with a hard disk seems to be a Bad Idea at least in my 13" mid-2010 MBP: my 320GB WD Scorpio Blue took over a minute to copy 60MB. That is so 80s.  &lt;/p&gt;
&lt;p&gt;Interestingly, when I put the hard drive back to where it belongs, and put a SSD in the slot it vacated, the performance of the hard drive went back up to nominal.  &lt;/p&gt;
&lt;p&gt;Any one planning to upgrade to a dual SSD+HDD configuration should leave the HDD where it is and replace SuperDrive with the SSD.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="PSA"/></entry><entry><title>Getting pyglet setup in OS X 10.7.2</title><link href="/getting-pyglet-setup-in-os-x-1072.html" rel="alternate"/><published>2012-01-27T04:58:00+11:00</published><updated>2012-01-27T04:58:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2012-01-27:/getting-pyglet-setup-in-os-x-1072.html</id><summary type="html">&lt;ol&gt;
&lt;li&gt;Create a virtual env and activate it&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;hg clone https://code.google.com/p/pyglet/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pushd pyglet; python setup.py install&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;popd&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;easy_install  pyobjc==2.3 &lt;em&gt;# the ==2.3 is required as of 2012-01-27, or pyobjc-core will not install&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;python -c "import pyglet"&lt;/span&gt; &lt;em&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;# this step should not fail &lt;/span&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve …&lt;/p&gt;</summary><content type="html">&lt;ol&gt;
&lt;li&gt;Create a virtual env and activate it&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;hg clone https://code.google.com/p/pyglet/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pushd pyglet; python setup.py install&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;popd&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;easy_install  pyobjc==2.3 &lt;em&gt;# the ==2.3 is required as of 2012-01-27, or pyobjc-core will not install&lt;/em&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;python -c "import pyglet"&lt;/span&gt; &lt;em&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;# this step should not fail &lt;/span&gt;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="code"/><category term="osx"/><category term="oss"/><category term="howto"/></entry><entry><title>3D Printing with Blender and UP!</title><link href="/3d-printing-with-blender-and-up.html" rel="alternate"/><published>2011-12-18T14:48:00+11:00</published><updated>2011-12-18T14:48:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-12-18:/3d-printing-with-blender-and-up.html</id><content type="html">&lt;ul&gt;
&lt;li&gt;No intersecting planes! These confuse the software into making voids without making scaffolding&lt;/li&gt;
&lt;li&gt;1 unit = 1mm&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Manchester encoding/decoding in LibHiJack</title><link href="/manchester-encodingdecoding-in-libhijack.html" rel="alternate"/><published>2011-11-15T04:42:00+11:00</published><updated>2011-11-15T04:42:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-11-15:/manchester-encodingdecoding-in-libhijack.html</id><summary type="html">&lt;div style="text-align: right;"&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;a href="http://code.google.com/p/hijack-main/"&gt;hijack&lt;/a&gt; &lt;a href="http://code.google.com/p/hijack-main/source/browse/#svn%2Ftrunk%2FiPhone%2FLibHiJack"&gt;iPhone library&lt;/a&gt; implements &lt;a href="http://en.wikipedia.org/wiki/Manchester_code"&gt;Manchester encoding&lt;/a&gt; for digital communication.  Manchester encoding maps 0 to high-low transition, and 1 to low-high transition.  &lt;/p&gt;
&lt;p&gt;The iPhone library generates the transitions using full or half period of a sine wave, using a full period when a bit run is detected. An example of …&lt;/p&gt;</summary><content type="html">&lt;div style="text-align: right;"&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;a href="http://code.google.com/p/hijack-main/"&gt;hijack&lt;/a&gt; &lt;a href="http://code.google.com/p/hijack-main/source/browse/#svn%2Ftrunk%2FiPhone%2FLibHiJack"&gt;iPhone library&lt;/a&gt; implements &lt;a href="http://en.wikipedia.org/wiki/Manchester_code"&gt;Manchester encoding&lt;/a&gt; for digital communication.  Manchester encoding maps 0 to high-low transition, and 1 to low-high transition.  &lt;/p&gt;
&lt;p&gt;The iPhone library generates the transitions using full or half period of a sine wave, using a full period when a bit run is detected. An example of this is shown below.  &lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: center;"&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;&lt;a href="/media/08b244_manchester.gif" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOmUxHtFJGNj-hyeRNXHkpQXficd3ow9O9U5VErxpkCBIc6q9sEk0aMwsUd23z4oWS-kZXhAjzLc0bLxn-bC28v_s9BBiiYYzPWFXSYDYSuh0pN8PByZQcAO79yUINFgiuBZp2KQ/s400/manchester.gif" data-border="0" width="400" height="280" /&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: center;"&gt;Manchester encoding of 0110011101 by libHiJack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Detection of Manchester encoding is relatively simple: first the signal is regenerated into a square wave by setting all values above 0 to 1 and 0 otherwise. The number of samples between transitions (0 to 1 or 1 to 0) is then measured. When this interval is within an acceptable range (as determined by the baud rate) the bit is read simply by taking the value of the regenerated square wave immediately after the transition. This works out nicely because 1 maps to a low-high transition, and the value immediately after transition is 1, while 0 maps to high-low transition, and the value immediately after transition is 0.  &lt;/p&gt;
&lt;p&gt;The important thing to note is that detection of a bit occurs at the transition from one bit to the next, and the code ignores transitions during a bit period. Specifically a transition must occur between 3/4 and 3/2 bit periods from last bit detection, otherwise it is ignored.  &lt;/p&gt;
&lt;p&gt;For example the transition between sample 64 and 96 is ignored because it occurs 1/2 a bit period since the last bit detection at sample 64.  &lt;/p&gt;
&lt;p&gt;Finally, the UART frame used consists of a start bit, eight data bits, one parity bits and one stop bit. Note my example doesn't include the parity bit since I reimplemented the encoding algorithm in python to produce the graph.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="electronics"/></entry><entry><title>Brendanites of the Brendanverse</title><link href="/brendanites-of-the-brendanverse.html" rel="alternate"/><published>2011-08-01T16:29:00+10:00</published><updated>2011-08-01T16:29:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-08-01:/brendanites-of-the-brendanverse.html</id><summary type="html">&lt;p&gt;Of all Brendanites, the worst off are the criminals and other malcontents. Water-boarding is par-for-course as is other cruel and unusual punishments, like electric-clamps-on-nipples and listening to boy bands non-stop. By the O'Neill doctrine, if it worked before then whatever it is is OK now and forever. Amen.  &lt;/p&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;

While criminals …&lt;/div&gt;</summary><content type="html">&lt;p&gt;Of all Brendanites, the worst off are the criminals and other malcontents. Water-boarding is par-for-course as is other cruel and unusual punishments, like electric-clamps-on-nipples and listening to boy bands non-stop. By the O'Neill doctrine, if it worked before then whatever it is is OK now and forever. Amen.  &lt;/p&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;

While criminals have it bad in Brendanverse, the entrepreneurs have it easy. Starting business in Brendanverse is simple: find a market and setup shop. No need to worry about established competition, they won't do things like undercut your prices or bad mouth you in front of their customers. No siree, that's not how Brendanverse works. 

&lt;/div&gt;

&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;



&lt;/div&gt;

&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;

You see, in Brendanverse a company that owns, say 70% of the market, will do nothing like leverage their market share and resources to drive out, hinder or crush their competitors. In fact, calling them competitors is a misnomer: it implies competition and we can't have that. Companies are more like friends, happily coexisting and sharing their toys, aka customers.

&lt;/div&gt;

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

Even more blessed than the entrepreneurs are the Chosen - the Journalists (not the Jews). They have all the right the Government has, including and not limited to reading people's emails and tapping their phones. These are &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;rights&lt;/span&gt; that, by the O'Neil Doctrine, the Government owes to journalist, because unlike the Government, a Journalist is the epitome of integrity and honesty. They rise above the law and accountability and other trifling matters like FOI requests.

&lt;/div&gt;

&lt;p&gt;Whoever they are though, every Brendanite is a completely rational human being unswayed by emotional rhetorics, who gives every opinion their due weight before making a decision.  &lt;/p&gt;
&lt;p&gt;What a brave new world, with such people in it.  &lt;/p&gt;
&lt;p&gt;--  &lt;/p&gt;
&lt;p&gt;Having had a glimpse of the mind of Brendan O'Neil, I can't help but think he is someone who when confronted with an uncomfortable question latches on to the nearest superficial answer and runs with it.  &lt;/p&gt;
&lt;p&gt;Some people call him a "passionate defender of free speech" which brings to mind the following quote by Jascha Heifetz:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“No matter what side of an argument you're on, you always find some people on your side that wish you were on the other side.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I wonder if he supports the right of people to yell fire in theatres...  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve  &lt;/p&gt;</content><category term="posts"/><category term="rant"/><category term="australia"/><category term="qanda"/></entry><entry><title>git with multiple svn-remotes</title><link href="/git-with-multiple-svn-remotes.html" rel="alternate"/><published>2011-05-29T00:15:00+10:00</published><updated>2011-05-29T00:15:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-29:/git-with-multiple-svn-remotes.html</id><summary type="html">&lt;p&gt;Use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git init&lt;/span&gt; to create an empty git repository, then edit &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;.git/config&lt;/span&gt; to add the svn remotes:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;[core]&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;repositoryformatversion = 0&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;filemode = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bare = false&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;logallrefupdates = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ignorecase = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;[svn-remote "svn"]&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;url = file:///home/steve/code/svn-repos/foo&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;fetch = trunk:refs/remotes/trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branches = branches/*:refs/remotes/*&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tags = tags/*:refs …&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;Use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git init&lt;/span&gt; to create an empty git repository, then edit &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;.git/config&lt;/span&gt; to add the svn remotes:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;[core]&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;repositoryformatversion = 0&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;filemode = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;bare = false&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;logallrefupdates = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ignorecase = true&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;[svn-remote "svn"]&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;url = file:///home/steve/code/svn-repos/foo&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;fetch = trunk:refs/remotes/trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branches = branches/*:refs/remotes/*&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tags = tags/*:refs/remotes/tags/*&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;[svn-remote "svn-other"]&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;url = file:///home/steve/tmp/foo-svn-other&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;fetch = trunk:refs/remotes/svn-other/trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;branches = branches/*:refs/remotes/svn-other/*&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tags = tags/*:refs/remotes/svn-other/tags/*&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;It is assumed at this point svn-other is simply a copy of svn. They are allowed to diverge later.  &lt;/p&gt;
&lt;p&gt;Do a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;git svn fetch -R svn&lt;/span&gt; to initialise git svn. To manage commits between the two svn remotes, create local tracking branches of remote branches:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;\$ git checkout -b trunk-other remotes/svn-other/trunk&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;I ended up with something like :  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  master&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;* trunk-other&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  remotes/svn-other/trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  remotes/trunk&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;You can pull changes from one svn repository then push it to another:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;\&lt;span class="math"&gt;\( git svn fetch -R svn&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;r1 = 049fed636e283096986e0eefa261be0525d8d7b3 (refs/remotes/trunk)&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;Checked out HEAD:&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;\\)&lt;/span&gt; git svn dcommit&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Committing to file:///home/steve/tmp/foo-svn-other/trunk ...&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;A&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;test&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Committed r2&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;A&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;test&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;r2 = 10613af6701eca4b30a3ff89ab408e38ca157fa0 (refs/remotes/svn-other/trunk)&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;No changes between current HEAD and refs/remotes/svn-other/trunk&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Resetting to the latest refs/remotes/svn-other/trunk&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="posts"/><category term="svn"/><category term="git"/><category term="software"/></entry><entry><title>Find and svn add all untracked files</title><link href="/find-and-svn-add-all-untracked-files.html" rel="alternate"/><published>2011-05-18T08:17:00+10:00</published><updated>2011-05-18T08:17:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-18:/find-and-svn-add-all-untracked-files.html</id><content type="html">&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;svn st | grep '^?' | sed 's/^[? ]*/"/' | sed 's/\$/"/' | xargs svn add&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>How to Leave LAX with a microsim</title><link href="/how-to-leave-lax-with-a-microsim.html" rel="alternate"/><published>2011-05-16T06:17:00+10:00</published><updated>2011-05-16T06:17:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-16:/how-to-leave-lax-with-a-microsim.html</id><content type="html">&lt;p&gt;It is possible to leave Australia without an overseas SIM card and&lt;br&gt;
Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Firehol and mDNS</title><link href="/firehol-and-mdns.html" rel="alternate"/><published>2011-05-08T03:05:00+10:00</published><updated>2011-05-08T03:05:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-08:/firehol-and-mdns.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/7914a2_Screen_shot_2011_05_08_at_1.04.25_PM.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/7914a2_Screen_shot_2011_05_08_at_1.04.25_PM.png" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Here is my &lt;a href="http://firehol.sourceforge.net/"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;firehol&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;.conf&lt;/span&gt; that allows multicast mDNS packets through:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;# define mdns so we will accept it&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;server_mdns_ports="udp/5353"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;client_mdns_ports="5353"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;interface eth+ multi&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   policy return&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   server mdns accept&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   server multicast accept                                                                                                        &lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;interface eth+ home src "\${home_ips}"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    server  all         accept&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    client  all         accept&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Initially I had the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;server …&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/7914a2_Screen_shot_2011_05_08_at_1.04.25_PM.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/7914a2_Screen_shot_2011_05_08_at_1.04.25_PM.png" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Here is my &lt;a href="http://firehol.sourceforge.net/"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;firehol&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;.conf&lt;/span&gt; that allows multicast mDNS packets through:  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;# define mdns so we will accept it&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;server_mdns_ports="udp/5353"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;client_mdns_ports="5353"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;interface eth+ multi&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   policy return&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   server mdns accept&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;   server multicast accept                                                                                                        &lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;interface eth+ home src "\${home_ips}"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    server  all         accept&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;    client  all         accept&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Initially I had the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;server mdns accept&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;server multicast accept&lt;/span&gt; inside the home interface, but this didn't work. Firehol's developer, Mr Costa Tsaousis, pointed out that s&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;rc "\${home_ips}" &lt;/span&gt;on &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;home&lt;/span&gt; would exclude broadcast packets sent from MAC addresses, thus the second interface definition (&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;multi&lt;/span&gt;).  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>Success for Science</title><link href="/success-for-science.html" rel="alternate"/><published>2011-05-07T12:23:00+10:00</published><updated>2011-05-07T12:23:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-07:/success-for-science.html</id><summary type="html">&lt;p&gt;Just finished packaging my engineering thesis project into a more portable format: an altoids tin! I have seen people put some neat stuff inside them, and I am chuffed I managed to as well :) Though I had to cut through the lid for the display. And I only had to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Just finished packaging my engineering thesis project into a more portable format: an altoids tin! I have seen people put some neat stuff inside them, and I am chuffed I managed to as well :) Though I had to cut through the lid for the display. And I only had to use the hacksaw once.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/eed5e0_package1.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0IXvspLkkBYItQc3A5MYpXc46OPcYNQd4PefHS68BWghPA5zUkOaZRf2XzJTKiRczqr7ELyuJEYHmIMzPUp18W6Hx97Y0Xa_sS0VcD_b61m1je2rM58VPCgSjV0hkSkz5Vigd2A/s400/package1.jpg" data-border="0" width="400" height="191" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;



&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="electronics"/><category term="arduino"/><category term="diy"/></entry><entry><title>Improved the DSO Nano Probes</title><link href="/improved-the-dso-nano-probes.html" rel="alternate"/><published>2011-05-06T05:59:00+10:00</published><updated>2011-05-06T05:59:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-05-06:/improved-the-dso-nano-probes.html</id><summary type="html">&lt;p&gt;Got parts from element14 today: &lt;a href="http://au.element14.com/deltron/575-0100/probe-test-mini-black/dp/1193805?Ntt=1193805"&gt;hook&lt;/a&gt; &lt;a href="http://au.element14.com/deltron/575-0500/probe-test-mini-red/dp/1193802?Ntt=1193802"&gt;probes&lt;/a&gt; and &lt;a href="http://au.element14.com/lumberg/wkls-2/plug-3-5mm-jack-r-a-mono/dp/1243265?Ntt=1243265"&gt;right-angle 3.5mm mono plug&lt;/a&gt;. Modded my DSO nano probes, replacing the micro-tweezer probes and the connector. Interestingly the factory probed using a stereo connector, but the mono replacement works just as well.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/b7a7eb_Photo_May_06_252C_15_20_12.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggtzJTVVbm1gpiJrFAUjRnBxxOHvkRjuOnoju-JzI241Fy0vk2lvl6VKNOulRtEy5-5xygZQrx0q-cJyQDZvtJpTeJTy4paGdeWg1Ad-RzaiJmtHLxEmL4KSXdw0srni-M0kFSsQ/s200/Photo+May+06%252C+15+20+12.jpg" data-border="0" width="165" height="200" /&gt;&lt;/a&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW7BXmjDNdx2gBaSr3XufC2-Vu8tK0TEAH8qzrpxaVDsptZxULnDV41LKcMPf_LJ68G6RvLpLSnK1whXN__Y2rUhIZWShEqtk-tXwpexSUc0gOenIE1DJgZua2IG3av3Yy0Ufn3Q/s1600/Photo+May+06%252C+15+19+49.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW7BXmjDNdx2gBaSr3XufC2-Vu8tK0TEAH8qzrpxaVDsptZxULnDV41LKcMPf_LJ68G6RvLpLSnK1whXN__Y2rUhIZWShEqtk-tXwpexSUc0gOenIE1DJgZua2IG3av3Yy0Ufn3Q/s200/Photo+May+06%252C+15+19+49.jpg" data-border="0" width="170" height="200" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;This along with BenF 3.61a firmware upgrade has …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Got parts from element14 today: &lt;a href="http://au.element14.com/deltron/575-0100/probe-test-mini-black/dp/1193805?Ntt=1193805"&gt;hook&lt;/a&gt; &lt;a href="http://au.element14.com/deltron/575-0500/probe-test-mini-red/dp/1193802?Ntt=1193802"&gt;probes&lt;/a&gt; and &lt;a href="http://au.element14.com/lumberg/wkls-2/plug-3-5mm-jack-r-a-mono/dp/1243265?Ntt=1243265"&gt;right-angle 3.5mm mono plug&lt;/a&gt;. Modded my DSO nano probes, replacing the micro-tweezer probes and the connector. Interestingly the factory probed using a stereo connector, but the mono replacement works just as well.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/b7a7eb_Photo_May_06_252C_15_20_12.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggtzJTVVbm1gpiJrFAUjRnBxxOHvkRjuOnoju-JzI241Fy0vk2lvl6VKNOulRtEy5-5xygZQrx0q-cJyQDZvtJpTeJTy4paGdeWg1Ad-RzaiJmtHLxEmL4KSXdw0srni-M0kFSsQ/s200/Photo+May+06%252C+15+20+12.jpg" data-border="0" width="165" height="200" /&gt;&lt;/a&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW7BXmjDNdx2gBaSr3XufC2-Vu8tK0TEAH8qzrpxaVDsptZxULnDV41LKcMPf_LJ68G6RvLpLSnK1whXN__Y2rUhIZWShEqtk-tXwpexSUc0gOenIE1DJgZua2IG3av3Yy0Ufn3Q/s1600/Photo+May+06%252C+15+19+49.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhW7BXmjDNdx2gBaSr3XufC2-Vu8tK0TEAH8qzrpxaVDsptZxULnDV41LKcMPf_LJ68G6RvLpLSnK1whXN__Y2rUhIZWShEqtk-tXwpexSUc0gOenIE1DJgZua2IG3av3Yy0Ufn3Q/s200/Photo+May+06%252C+15+19+49.jpg" data-border="0" width="170" height="200" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;This along with BenF 3.61a firmware upgrade has improved the DSO nano somewhere between 100 to 1000 times.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="electronics diy"/></entry><entry><title>My Err99 Resolution</title><link href="/my-err99-resolution.html" rel="alternate"/><published>2011-04-23T05:05:00+10:00</published><updated>2011-04-23T05:05:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-04-23:/my-err99-resolution.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: left;"&gt;

&lt;a href="/media/0e3f5d_canon_err99.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/0e3f5d_canon_err99.jpg" data-border="0" /&gt;&lt;/a&gt;Err99 is a somwhat common error encountered by Canon DSLR users. Because it is something of a catch-all error code a variety of causes and resolutions can be found via google. In my case the error was fixed by a firmware upgrade while it was in the hands of Canon …&lt;/div&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: left;"&gt;

&lt;a href="/media/0e3f5d_canon_err99.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/0e3f5d_canon_err99.jpg" data-border="0" /&gt;&lt;/a&gt;Err99 is a somwhat common error encountered by Canon DSLR users. Because it is something of a catch-all error code a variety of causes and resolutions can be found via google. In my case the error was fixed by a firmware upgrade while it was in the hands of Canon camera servicing personnel, so if you find you have exhausted all options, send it back to Canon!

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;

For what it is worth, the Camera already had what I thought was the latest firmware, perhaps I downloaded the wrong version, or Canon worked some additional magic.

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: left;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

Cheers,

&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

Steve

&lt;/div&gt;</content><category term="posts"/><category term="canon"/><category term="PSA"/></entry><entry><title>Another Galaxy Down</title><link href="/another-galaxy-down.html" rel="alternate"/><published>2011-04-22T14:16:00+10:00</published><updated>2011-04-22T14:16:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-04-22:/another-galaxy-down.html</id><content type="html">&lt;p&gt;Found NGC 4594, aka the Sombrero Galaxy.  &lt;/p&gt;
&lt;div style="text-align: center;"&gt;

&lt;a href="/media/8b5d59_IMG_0024.JPG" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj940qJgRWWOr3sdAZWUmxlcArGKdVMDQ5Hw3o82i6FalCqOPVlWPE-d1N8hM2ZJmb4KWqkuZ7_vh-9MNe-Sm7jwUKfGO8REGKVJSga40O_vdf8r3DX8r76EQXvemBpLWiNqd4ipA/s400/IMG_0024.JPG" data-border="0" width="308" height="400" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div style="text-align: center;"&gt;



&lt;/div&gt;

&lt;div style="text-align: left;"&gt;

In addition also found what is probably cataracts in my eyes \&gt;.\&lt;

&lt;/div&gt;

&lt;p&gt;&lt;span id="goog_1376205977"&gt;&lt;/span&gt;&lt;span id="goog_1376205978"&gt;&lt;/span&gt;&lt;br&gt;
Cheers,  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;



&lt;/div&gt;

&lt;p&gt;Steve&lt;/p&gt;</content><category term="posts"/><category term="astronomy"/></entry><entry><title>TIL: const, NSError, NSApplicationsupportDirectory</title><link href="/til-const-nserror-nsapplicationsupportdirectory.html" rel="alternate"/><published>2011-04-17T15:34:00+10:00</published><updated>2011-04-17T15:34:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-04-17:/til-const-nserror-nsapplicationsupportdirectory.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;const char *foo;&lt;/span&gt; is not the same as &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char * const foo;&lt;/span&gt; The former declares a pointer to constant &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char&lt;/span&gt;, while the latter declares a constant pointer to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;- [NSError localizedDescription]&lt;/span&gt; returns the object for key &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;NSLocalizedDescriptionKey&lt;/span&gt; in the error's &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;userInfo&lt;/span&gt; dictionary. I always wondered how to set it since there …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;const char *foo;&lt;/span&gt; is not the same as &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char * const foo;&lt;/span&gt; The former declares a pointer to constant &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char&lt;/span&gt;, while the latter declares a constant pointer to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;char&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;- [NSError localizedDescription]&lt;/span&gt; returns the object for key &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;NSLocalizedDescriptionKey&lt;/span&gt; in the error's &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;userInfo&lt;/span&gt; dictionary. I always wondered how to set it since there is no &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;setLocalizedDescription:.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;On iOS the application's &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Application Support&lt;/span&gt; directory doesn't seem to exist by default, unlike the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Documents&lt;/span&gt; directory. This has to be created programmatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>ICBM: iOS OTA Distribution Webapp</title><link href="/icbm-ios-ota-distribution-webapp.html" rel="alternate"/><published>2011-04-15T12:44:00+10:00</published><updated>2011-04-15T12:44:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-04-15:/icbm-ios-ota-distribution-webapp.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="http://bottlepy.org/docs/dev/_static/logo_nav.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="http://bottlepy.org/docs/dev/_static/logo_nav.png" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Finding myself in the position of needing to distribute several apps OTA and unable to use the more well known OTA services like &lt;a href="http://testflightapp.com/"&gt;testflightapp.com&lt;/a&gt; due to client concerns, I made my own, ICBM.  &lt;/p&gt;
&lt;p&gt;ICBM is a small python webapp built using my favourite webapp framework,  &lt;a href="https://github.com/defnull/bottle"&gt;bottle&lt;/a&gt;. You just put …&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="http://bottlepy.org/docs/dev/_static/logo_nav.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="http://bottlepy.org/docs/dev/_static/logo_nav.png" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Finding myself in the position of needing to distribute several apps OTA and unable to use the more well known OTA services like &lt;a href="http://testflightapp.com/"&gt;testflightapp.com&lt;/a&gt; due to client concerns, I made my own, ICBM.  &lt;/p&gt;
&lt;p&gt;ICBM is a small python webapp built using my favourite webapp framework,  &lt;a href="https://github.com/defnull/bottle"&gt;bottle&lt;/a&gt;. You just put your application along with icons and the Info.plist (not the binary one) into a directory, and ICBM will generate the required HTML page and manifest plist.  &lt;/p&gt;
&lt;p&gt;e.g.  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;icbm.py&lt;/li&gt;
&lt;li&gt;AwesomeApp/&lt;ul&gt;
&lt;li&gt;AwesomeApp.ipa&lt;/li&gt;
&lt;li&gt;Icon.png&lt;/li&gt;
&lt;li&gt;Icon_512.png&lt;/li&gt;
&lt;li&gt;AwesomeApp-Info.plist&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More detail over at its github page: &lt;a href="https://github.com/freespace/icbm"&gt;https://github.com/freespace/icbm&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/></entry><entry><title>How to Tell if You Will Like Sucker Punch</title><link href="/how-to-tell-if-you-will-like-sucker-punch.html" rel="alternate"/><published>2011-04-11T15:41:00+10:00</published><updated>2011-04-11T15:41:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2011-04-11:/how-to-tell-if-you-will-like-sucker-punch.html</id><content type="html">&lt;p&gt;Can you relate to the following image? If so, then yes.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="http://i.imgur.com/HjIZH.jpg" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="http://i.imgur.com/HjIZH.jpg" data-border="0" width="81" height="640" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div style="text-align: center;"&gt;



&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Broken OS X Installers and How to Fix Them</title><link href="/broken-os-x-installers-and-how-to-fix-them.html" rel="alternate"/><published>2011-03-26T14:42:00+11:00</published><updated>2011-03-26T14:42:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-03-26:/broken-os-x-installers-and-how-to-fix-them.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/2d78d4_pkg_001.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/2d78d4_pkg_001.jpg" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The installers Ralink provides for some of their chipsets, like the RT2770 does something retarded: they attempt to unload a kext in a pre-install script, and when it fails the script fails and the entire install fails.  &lt;/p&gt;
&lt;p&gt;This means on a new machine, or one that never had the kext …&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/2d78d4_pkg_001.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/2d78d4_pkg_001.jpg" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;The installers Ralink provides for some of their chipsets, like the RT2770 does something retarded: they attempt to unload a kext in a pre-install script, and when it fails the script fails and the entire install fails.  &lt;/p&gt;
&lt;p&gt;This means on a new machine, or one that never had the kext installed, you can't install their driver.  &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fail.&lt;/em&gt;  &lt;/p&gt;
&lt;p&gt;It used to be that pkg installers were just directories, and fixing something like this is easy: find the offending line and comment it out. But OS X 10.5 onwards introduced &lt;em&gt;flat pkgs.&lt;/em&gt; These don't give up their secrets so easily.  &lt;/p&gt;
&lt;p&gt;&lt;a href="http://reviews.cnet.com/8301-13727_7-10329617-263.html"&gt;An article on cnet&lt;/a&gt; tipped me off to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pkgutil&lt;/span&gt;, a program that is installed by default. It lets you expand a flat pkg into a directory, and more importantly, allows to repackage it as a flat pkg after you have excised the cause of your troubles. This last step is important because a flat pkg when unpacked has a different directory structure to a "normal" pkg and thus can not simply be &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;open&lt;/span&gt;'d.  &lt;/p&gt;
&lt;p&gt;Here is what I did to fix Ralink's installer:  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pkgutil --expand installer.pkg ~/Desktop/installer-expanded.pkg&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd ~/Desktop/installer-expanded.pkg/installroot.pkg/Scripts/&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;vim preinstall #alternatively, &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;for ppl unfamilar with vim:&lt;/span&gt;&lt;ol&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;open .&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;right click on preinstall, open in TextEdit.app&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;comment out the offending line which is trying to remove the kext&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;save and exit your editor&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd ~/Desktop&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pkgutil --flatten installer-expanded.pkg installer.pkg&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;open ./installer.pkg&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="software"/><category term="osx"/><category term="howto"/></entry><entry><title>Endianess, Thy art Sneaky</title><link href="/endianess-thy-art-sneaky.html" rel="alternate"/><published>2011-02-25T05:12:00+11:00</published><updated>2011-02-25T05:12:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-02-25:/endianess-thy-art-sneaky.html</id><summary type="html">&lt;p&gt;I took delivery of my Linksys WUSB600N V2 today and was very excited to get my G4 Mac Mini online. The many online sources suggests all I need to do is change a few values in an Info.plist. However as it turns out, that wasn't enough. In order for …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I took delivery of my Linksys WUSB600N V2 today and was very excited to get my G4 Mac Mini online. The many online sources suggests all I need to do is change a few values in an Info.plist. However as it turns out, that wasn't enough. In order for me to get it working, I had to change the values, but also write the new values in hexadecimal format. This is because even though 0x0079 translates to 121, that is only true for a little endian system. Likewise, 0x1737 also only translates to 5943 under a small endian system. Since OS X running on PPC is a big endian system, unless you write out the exact byte values using hexadecimal notation it isn't going to work.  &lt;/p&gt;
&lt;p&gt;So, for the record: Linksys WUSB600N V2 runs just fine on OS X 10.5.8 running on G4. It does 5GHz and successfully authenticates with my airport express, which the Monoprice USB 2.0 Wireless N it replaced didn't.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="osx"/><category term="computer"/></entry><entry><title>Tabbing in Vim With Tab Autocompletion</title><link href="/tabbing-in-vim-with-tab-autocompletion.html" rel="alternate"/><published>2011-02-24T13:03:00+11:00</published><updated>2011-02-24T13:03:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-02-24:/tabbing-in-vim-with-tab-autocompletion.html</id><summary type="html">&lt;p&gt;&lt;a href="/media/b029d5_vim.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/b029d5_vim.png" data-border="0" /&gt;&lt;/a&gt;I use vim with &lt;a href="http://vim.wikia.com/wiki/Autocomplete_with_TAB_when_typing_words"&gt;a tab autocompletion macro&lt;/a&gt;, and sometimes I really do want to insert a tab character and autocompletion gets in the way.  &lt;/p&gt;
&lt;p&gt;Today I found out that if I hold down shift and hit tab, a tab is inserted and tab autocompletion doesn't get triggered. Prior to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/media/b029d5_vim.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="/media/b029d5_vim.png" data-border="0" /&gt;&lt;/a&gt;I use vim with &lt;a href="http://vim.wikia.com/wiki/Autocomplete_with_TAB_when_typing_words"&gt;a tab autocompletion macro&lt;/a&gt;, and sometimes I really do want to insert a tab character and autocompletion gets in the way.  &lt;/p&gt;
&lt;p&gt;Today I found out that if I hold down shift and hit tab, a tab is inserted and tab autocompletion doesn't get triggered. Prior to this I have been adding a space then hitting tab, which leaves ugly little space-tab sequences in my files.  &lt;/p&gt;
&lt;p&gt;Hope this helps some one out there.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="vim"/><category term="software"/><category term="howto"/></entry><entry><title>iOS Toolbar Pagecurl Icon</title><link href="/ios-toolbar-pagecurl-icon.html" rel="alternate"/><published>2011-01-27T11:30:00+11:00</published><updated>2011-01-27T11:30:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-01-27:/ios-toolbar-pagecurl-icon.html</id><summary type="html">&lt;p&gt;iOS 4.x's page curl UIBarButtonItem comes in blue, and blue, and blue. If you set a UIToolbar's tintColor, then it disappears for some reason.  &lt;/p&gt;
&lt;p&gt;So I had to make a replacement. Since I use a lot of icons made and given away by awesome people, I feel it is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;iOS 4.x's page curl UIBarButtonItem comes in blue, and blue, and blue. If you set a UIToolbar's tintColor, then it disappears for some reason.  &lt;/p&gt;
&lt;p&gt;So I had to make a replacement. Since I use a lot of icons made and given away by awesome people, I feel it is only fair to contribute my share, small though it maybe.  &lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="/media/cbb079_pagecurl.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="/media/cbb079_pagecurl.png" data-border="0" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;/div&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;/div&gt;

&lt;p&gt;Released under &lt;a href="http://www.wikipedia.org/wiki/WTFPL"&gt;WTFPL.&lt;/a&gt; Though it would be nice to hear from you if you do use it :)  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>iPhone 4 layer export script for Gimp</title><link href="/iphone-4-layer-export-script-for-gimp.html" rel="alternate"/><published>2011-01-27T11:29:00+11:00</published><updated>2011-01-27T11:29:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-01-27:/iphone-4-layer-export-script-for-gimp.html</id><summary type="html">&lt;p&gt;I often mockup iPhone interfaces on the &lt;a href="http://www.gimp.org/"&gt;Gimp&lt;/a&gt;, then exporting each layer for use as backgrounds. For iOS 4 each image needs to be exported twice: one at full resolution with @2x in its filename, and once at half-resolution without the @2x. e.g. nav_bg@2x.png and nav_bg.png …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I often mockup iPhone interfaces on the &lt;a href="http://www.gimp.org/"&gt;Gimp&lt;/a&gt;, then exporting each layer for use as backgrounds. For iOS 4 each image needs to be exported twice: one at full resolution with @2x in its filename, and once at half-resolution without the @2x. e.g. nav_bg@2x.png and nav_bg.png.  &lt;/p&gt;
&lt;p&gt;Exporting layers by hand gets old real quick. Thankfully the Gimp supports scripting in my favourite language: python. Even better, Chris Mohler had already written a script to do something very similar, so all I needed to do was make some simple adjustments:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c1"&gt;# -*- coding: &amp;lt;utf-8&amp;gt; -*-&lt;/span&gt;
&lt;span class="c1"&gt;# Author: Chris Mohler &amp;lt;cr33dog@gmail.com&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;# Copyright 2009 Chris Mohler&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;quot;Only Visible&amp;quot; and filename formatting introduced by mh&lt;/span&gt;
&lt;span class="c1"&gt;# License: GPL v3+&lt;/span&gt;
&lt;span class="c1"&gt;# Version 0.4&lt;/span&gt;
&lt;span class="c1"&gt;# GIMP plugin to export layers as PNGs&lt;/span&gt;
&lt;span class="c1"&gt;# modified by Shuning Bian 2011&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;gimpfu&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;gettext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gimp20-python&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gimp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;locale_directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;unicode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;format_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;layername&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;filename1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layername&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;@2x.png&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;filename2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layername&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;.png&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filename1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;filename2&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_layers_to_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;export_layers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duplicate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;savelayers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;get_layers_to_export&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;savelayers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;visible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gimp_layer_remove_mask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;filename1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;filename2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;format_filename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;fullpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filename1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duplicate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_png_save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fullpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filename1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;imgwidth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gimp_image_width&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;imgheight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gimp_image_height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gimp_image_scale_full&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;imgwidth&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;imgheight&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;fullpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filename2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;pdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;file_png_save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fullpath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;filename2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;dupe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove_layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;proc_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;python-fu-export-layers-iphone4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;blurb&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Export visible layers as PNG&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Export all visible layers as individual PNG files.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Chris Mohler &amp;lt;cr33dog@gmail.com&amp;gt; + sbian&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;copyright&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Chris Mohler&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2009&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;as _PNG&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;imagetypes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PF_IMAGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;img&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Image&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PF_DIRNAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Save PNGs here&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getcwd&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;export_layers&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;menu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;Image&amp;gt;/File/E_xport Layers&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;gimp20-python&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gimp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;locale_directory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="python"/><category term="computer"/><category term="code"/><category term="software"/></entry><entry><title>Socket.IO Framing Protocol</title><link href="/socketio-framing-protocol.html" rel="alternate"/><published>2011-01-22T14:55:00+11:00</published><updated>2011-01-22T14:55:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-01-22:/socketio-framing-protocol.html</id><summary type="html">&lt;p&gt;&lt;a href="http://Socket.IO/"&gt;Socket.IO&lt;/a&gt; is a great library and framework that doesn't seem to have a good description of the protocol available. In interest of helping others when they google "socket.io framing protocol", this post was born.  &lt;/p&gt;
&lt;p&gt;The description of the framing protocol used by Socket.IO below is taken from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://Socket.IO/"&gt;Socket.IO&lt;/a&gt; is a great library and framework that doesn't seem to have a good description of the protocol available. In interest of helping others when they google "socket.io framing protocol", this post was born.  &lt;/p&gt;
&lt;p&gt;The description of the framing protocol used by Socket.IO below is taken from &lt;a href="https://github.com/ajaxorg/Socket.IO-node"&gt;ajaxorg's Socket.IO-node fork on github&lt;/a&gt;. I have made some changes with regards to the annotations, specifically that they must be terminated by with newline. This description is current for v0.6+.  &lt;/p&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Socket.IO Framing Protocol&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Socket.IO 's framing protocol is &lt;em&gt;on top of&lt;/em&gt; the underlying transport. Messages have the following format:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;(message type)":"(content length)":"(data)","&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Where message type is one of:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;0&lt;/span&gt; for forced disconnect - no data is sent, always sent as &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;0:0:,&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;1&lt;/span&gt; for messages - see below&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;2&lt;/span&gt; for heartbeats - data is an integer, e.g. &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;2:1:0, &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;3&lt;/span&gt; for session ID handshake - data is a session ID, e.g. &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;3:3:253,&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;

&lt;span class="Apple-style-span" style="font-size: large;"&gt;  
&lt;/span&gt;  
&lt;span class="Apple-style-span" style="font-size: large;"&gt;Messages&lt;/span&gt;  
&lt;span class="Apple-style-span" style="font-size: large;"&gt;  
&lt;/span&gt;

&lt;/div&gt;

&lt;div&gt;

If you were familiar with the Socket.IO protocol you will notice there appears to be no way now to specify a message contains JSON data as the new protocol has no counter part to the JSON Frame indicator &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;~j~&lt;/span&gt;. Fear not - the new Socket.IO protocol provides a means for this and many other possible extensions via **annotations** which maybe attachd to messages in a manner reminiscent of HTTP headers. 

&lt;/div&gt;

&lt;div&gt;


A Socket.IO message now has the following format:  

&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;\[key\[:value\]\["\n"key\[:value\]\]\["\n"key\[:value\]..."\n"\]":"\[message\]&lt;/span&gt;

In words: annotations are key-value pairs where the value may be omitted. Individual annotations are delimited by newlines, and annotations are separated from the message by another newline.  

From examining the Socket.IO source, if no annotation is present then there should be no newline, but the colon is still required.  

A JSON message is sent with a single annotation with key of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;**j**&lt;/span&gt; and no value. Below is an example taken from a debugging session:  

&gt; &lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&gt;
&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;1:128:j&lt;/span&gt;
&gt;
&gt; &lt;/div&gt;
&gt;
&gt; &lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&gt;
&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;:{"method":"create_user","params":\[{"password":"jhhgffufuhgv","email":"h@h.com"}\],"id":"83BCA0A8-7F9D-428A-A546-2EFCBDC20AB3"},&lt;/span&gt;
&gt;
&gt; &lt;/div&gt;

Note there is a newline after the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;**j**&lt;/span&gt;. The official Socket.IO client uses an additional annotation: **&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;r&lt;/span&gt;** for realm. e.g.  

&gt; &lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&gt;
&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;1:18:r:chat&lt;/span&gt;
&gt;
&gt; &lt;/div&gt;
&gt;
&gt; &lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;
&gt;
&gt; &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;:Hello world,&lt;/span&gt;
&gt;
&gt; &lt;/div&gt;

Note the newline after **&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;chat&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;.&lt;/span&gt;**  
**&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  
&lt;/span&gt;**

&lt;/div&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>UIGraphicsBeginImageContext on iPhone 4</title><link href="/uigraphicsbeginimagecontext-on-iphone-4.html" rel="alternate"/><published>2011-01-16T10:21:00+11:00</published><updated>2011-01-16T10:21:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2011-01-16:/uigraphicsbeginimagecontext-on-iphone-4.html</id><summary type="html">&lt;p&gt;I generate &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIImages&lt;/span&gt; in some of my iOS applications, and prior to the iPhone 4 they all worked fine. With the introduction of the iPhone 4 and Retina Display, I realised my generated images were blurry even though I am rendering them at twice the resolution.  &lt;/p&gt;
&lt;p&gt;It turns out this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I generate &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIImages&lt;/span&gt; in some of my iOS applications, and prior to the iPhone 4 they all worked fine. With the introduction of the iPhone 4 and Retina Display, I realised my generated images were blurry even though I am rendering them at twice the resolution.  &lt;/p&gt;
&lt;p&gt;It turns out this is due to the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;scale&lt;/span&gt; property of my generated &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIImages&lt;/span&gt; being set to 1. This is mainly due to my use of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIGraphicsBeginImageContext(),&lt;/span&gt; which creates a bitmap context that is a) non-opaque and b) &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;scale&lt;/span&gt;=1. The fix is quite simple - use &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIGraphicsBeginImageContextWithOptions() &lt;/span&gt;and specify the scale appropriately.  &lt;/p&gt;
&lt;p&gt;For images derived from an existing image, e.g. rotating an existing image, it is sufficient to use the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;scale&lt;/span&gt; property of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;UIImage&lt;/span&gt;. For images created "from scratch", I use the following bit of code:  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="bp"&gt;UIScreen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mainScreen&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;respondsToSelector&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;@selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;UIGraphicsBeginImageContextWithOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;UIScreen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mainScreen&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UIGraphicsBeginImageContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div&gt;

&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  
&lt;/span&gt;Cheers,  
Steve

&lt;/div&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>Pulse-o-matic now on App Store</title><link href="/pulse-o-matic-now-on-app-store.html" rel="alternate"/><published>2010-12-16T00:05:00+11:00</published><updated>2010-12-16T00:05:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2010-12-16:/pulse-o-matic-now-on-app-store.html</id><content type="html">&lt;p&gt;It took a month and a bit, but &lt;a href="http://itunes.apple.com/au/app/pulse-o-matic/id406482970?mt=8"&gt;Pulse-o-matic is finally on the App Store&lt;/a&gt;. For my loyal followers (all 3 of you), email me for a promotion code :)  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="software"/></entry><entry><title>On Wikileaks and World Stability</title><link href="/on-wikileaks-and-world-stability.html" rel="alternate"/><published>2010-12-07T13:54:00+11:00</published><updated>2010-12-07T13:54:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2010-12-07:/on-wikileaks-and-world-stability.html</id><summary type="html">&lt;p&gt;Since the release of US embassy cables (aka &lt;a href="http://twitter.com/#search?q=%23cablegate"&gt;#cablegate&lt;/a&gt;), many have accused wikileaks of being irresponsible on the argument that what is revealed will retard progress or even destablise world politics.  &lt;/p&gt;
&lt;p&gt;However, 15 days after the release of these cables, we have observed no breakdown in negotiations, no cooling of …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Since the release of US embassy cables (aka &lt;a href="http://twitter.com/#search?q=%23cablegate"&gt;#cablegate&lt;/a&gt;), many have accused wikileaks of being irresponsible on the argument that what is revealed will retard progress or even destablise world politics.  &lt;/p&gt;
&lt;p&gt;However, 15 days after the release of these cables, we have observed no breakdown in negotiations, no cooling of relations, and no increase in aggression, even from those states the world is most weary of - Iran and North Korea.  &lt;/p&gt;
&lt;p&gt;I see nothing unusual about this.  &lt;/p&gt;
&lt;p&gt;In my opinion, the documents revealed no real surprises for the states players - in my opinion the diplomatic services of the states involved would have already known or at least suspected the attitudes and opinions contained in cables. I find it unlikely that US diplomats have such distinction and trust amongst their colleagues that they are privy to the confessions to exclusion of all others.  &lt;/p&gt;
&lt;p&gt;Having said that, cablegate will certainly lead to many more awkward moments across the negotiating table. Will diplomats sabotage negotiations over "blunt assessments" of themselves?   &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Thoughts on HTML, computer programs, and programming languages</title><link href="/thoughts-on-html-computer-programs-and-programming-languages.html" rel="alternate"/><published>2010-09-21T01:29:00+10:00</published><updated>2010-09-21T01:29:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-09-21:/thoughts-on-html-computer-programs-and-programming-languages.html</id><summary type="html">&lt;p&gt;I would like to start this post off by saying that emotionally I agree with the sentiment that HTML is not a programming language. Intellectually, however, my position is that HTML &lt;strong&gt;is&lt;/strong&gt; a programming language.  &lt;/p&gt;
&lt;p&gt;My argument for HTML as a programming language is very abstract, and to put it …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I would like to start this post off by saying that emotionally I agree with the sentiment that HTML is not a programming language. Intellectually, however, my position is that HTML &lt;strong&gt;is&lt;/strong&gt; a programming language.  &lt;/p&gt;
&lt;p&gt;My argument for HTML as a programming language is very abstract, and to put it simply: programming languages are used to express instructions to the computer on what to do. HTML instructs the computer on how to display content, therefore HTML is a programming language. Against this argument are the following, which can be encountered on any number of programming websites.  &lt;/p&gt;
&lt;p&gt;The most common argument against HTML being a programming language is that it describes itself as a markup language, as evident by the M in HTML. I find this argument wanting on 2 fronts: a) it implicitly assumes that a markup language can not be a programming language. TEX is a good example of a language which 99% of the time is used for markup, and the other 1% for programming; b) this argument is superficial. It implies if I was to simply rename HTML to HTPL, hypertext programming language, then &lt;strong&gt;&lt;em&gt;*poof*&lt;/em&gt;&lt;/strong&gt; now it is a programming language without having changed any of its characteristics. A rose by any other name...  &lt;/p&gt;
&lt;p&gt;A better argument is that HTML doesn't have control structures, whereas programming languages do. Suppose we accept this argument, which implicitly requires programming languages to support control structures. Consider a strict subset of LOGO, called miniLOGO that contains only the turtle graphics part of LOGO and nothing else - no loops, no conditionals, no control structures. By the definition we have assumed here, miniLOGO isn't a programming language. Now suppose you write a program in miniLOGO to draw "hello world"  on the screen, what have you written? I (and most people) say it is a program. This then presents a problem: you should not be able to write a program with a not-programming-language. At least it is a problem for me.  &lt;/p&gt;
&lt;p&gt;Suppose now you say no, the miniLOGO hello world isn't a program, and you give one of two reasons - that it doesn't contain control structures or that it wasn't written in a programming language. The first reason implicitly defines all programs as those containing control structures. I can not accept this reason because you can make a non-program a program by injecting a control structure with no side effect, and it is no less absurd and no more useful than the accepting HTML as a programming language. Not to mention the millions of introductory programming texts that will need to be rewritten so "hello world" contains an unecessary control structure. (&lt;span style="font-size: xx-small;"&gt;There are those who will then say: there ARE control structures, they are just a few levels of abstractions down. Well there are similar control structures in a browser. We do not worry about the rest of the abstraction stack, only the top of it&lt;/span&gt;).  &lt;/p&gt;
&lt;p&gt;For the second reason, consider what happens if I write the same program in full is-a-programming-language LOGO. Now it is a program by the virtue of having been written in a programming language, which brings us to an uncomfortable place: now we two things which are absolutely identical, but one is a program and one isn't by virtue of their parentage. Accepting this position is no more absurd than accepting that HTML is a programming language.  &lt;/p&gt;
&lt;p&gt;The final argument I will discuss is that my definition is such a generic definition just about anything is a programming language, therefore that definition is next to useless. This I agree with. However as I have (hopefully) demonstrated, it isn't easy to come up with a definition of what is a programming language (or in fact what is a program) that isn't contradictory or would invalidate millions of simple programs around the world.  &lt;/p&gt;
&lt;p&gt;I am still giving this issue thought, but until I am a more learned person in CS and possibly philosophy, my choice is between a definition of programming languages with low discriminatory powers, or ones which are fickle and contradictory.  &lt;/p&gt;
&lt;p&gt;HTML-is-a-programming-language, I choose you!  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="rant"/><category term="code"/><category term="software"/></entry><entry><title>Avoiding tag collisions</title><link href="/avoiding-tag-collisions.html" rel="alternate"/><published>2010-09-20T14:29:00+10:00</published><updated>2010-09-20T14:29:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-09-20:/avoiding-tag-collisions.html</id><content type="html">&lt;p&gt;UIViews in UIKit has a tag property which is very handy for marking views then retrieving them later. I am always worried though I will use the same tag for views in the same view hierarchy  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Script to read iPhone stack trace</title><link href="/script-to-read-iphone-stack-trace.html" rel="alternate"/><published>2010-07-10T11:43:00+10:00</published><updated>2010-07-10T11:43:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-07-10:/script-to-read-iphone-stack-trace.html</id><content type="html">&lt;p&gt;Sometimes my iPhone apps would crash and all I would get is a stack trace even when I run in Debug mode. Using atos wou&lt;br&gt;
Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/></entry><entry><title>Why Even Techies aren't Immune from the Filter</title><link href="/why-even-techies-arent-immune-from-the-filter.html" rel="alternate"/><published>2010-07-09T10:22:00+10:00</published><updated>2010-07-09T10:22:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-07-09:/why-even-techies-arent-immune-from-the-filter.html</id><summary type="html">&lt;p&gt;Of late I have seen statements from technologically inclined individuals along the lines of:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am not worried about the filter. Even if they put it in it will just slow things down a bit but we all know how to get around it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At first glance this seems reasonable …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Of late I have seen statements from technologically inclined individuals along the lines of:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am not worried about the filter. Even if they put it in it will just slow things down a bit but we all know how to get around it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At first glance this seems reasonable, after all it is true. It however ignores the fact the filter is not just a mechanism for stopping "naughty" content. The government can easily abused the filter and use it monitor &lt;strong&gt;&lt;em&gt;attempts&lt;/em&gt;&lt;/strong&gt; to access blocked content. In other words the government will be able to construct a list of "naughty" people.  &lt;/p&gt;
&lt;p&gt;You might ask  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What's the problem with that? Surely having a list of people who attempted to access child porn can only be a good thing&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you are asking this question, then you have been victim to Conroy's propaganda. The filter doesn't block &lt;em&gt;just&lt;/em&gt; child pornography, it blocks all refused classification (RC) content. At least it is &lt;em&gt;suppose&lt;/em&gt; to. The list of websites to be blocked will not be available for scrutiny. In other words, if the filter were to block content on such controversial topics such as abortion or euthanasia you won't know until you have attempted to access such content. By then it would be too late - the government now &lt;strong&gt;&lt;em&gt;knows&lt;/em&gt;&lt;/strong&gt; you tried.  &lt;/p&gt;
&lt;p&gt;The number of ways such a list of "naughty" people can be abused is beyond counting. Suppose the police needs a few child pornography arrests to look good. They just need to go through the list looking for a few poor souls who stumbled on their internet travels. Bang! A list of people whose privacy will be thoroughly violated as the police fishes through their background looking for dirt. God help them if they have actually broke some trivial law in our complex legal system.  &lt;/p&gt;
&lt;p&gt;But wait, you say,  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Isn't attempting to access refused classification material &lt;strong&gt;&lt;em&gt;wrong&lt;/em&gt;&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The answer is no, unless it is child pornography. The national classification code allows adult to read, hear, and see what they want:  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Classification decisions are to give effect, as far as possible, to the following principles:&lt;/p&gt;
&lt;p&gt;(a) adults should be able to read, hear and see what they want;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;RC material can not be shown, sold, and possession for the purpose of sale or display is illegal. But to consume it with in the privacy of your own home is no crime [1]. As an adult what you chose to read, hear and see is your own &lt;strong&gt;&lt;em&gt;private&lt;/em&gt;&lt;/strong&gt; business.  &lt;/p&gt;
&lt;p&gt;I am well aware this is a slippery slope argument, however I don't think it is outrageous or preposterous. Governments love to monitor what their citizens do [2], censor what they see, and control what they do. That is almost by definition. To imagine the government to pass up on abusing the filter mechanism is difficult to imagine. It would require &lt;strong&gt;&lt;em&gt;integrity&lt;/em&gt;&lt;/strong&gt; on their part, something that has been conspicuously absent thus far.  &lt;/p&gt;
&lt;p&gt;Hang on, I hear you say,  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How does this affect me, who always uses an encrypted connection?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;

&lt;div&gt;

&lt;div&gt;

&lt;div&gt;

Because my dear Watson, the lack of clear text communication is in itself damning evidence to the government. It shows you are to hiding *something*. In next to no time they will bring out the old fallacy:  

&gt; If you have done nothing wrong, what have you to hide?

Remember that Conroy is so ***incompetent*** he doesn't even know online banking is encrypted.  

The bottom line is this: don't allow this invasion of our privacy the chance to snowball just because it doesn't inconvenience you (yet). Nib it in the bud.  

At the next election, vote below the line and vote for the parties against the filter: the Greens \[3\], the Nationals \[4\], and if they make it in time, the Pirate Party Australia \[5\].  

Cheers,  
Steve  

&lt;div&gt;



&lt;/div&gt;

&lt;div&gt;

\[1\] They did try to make it a crime, but sanity prevailed. http://www.parliament.nsw.gov.au/Prod/parlment/hansart.nsf/V3Key/LA19970515003

&lt;/div&gt;

&lt;div&gt;

\[2\] Just see how much the UK loves their surveillance, despite no evidence it actually lowers crime. 

&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;/div&gt;

&lt;div&gt;

\[3\] Greens might trade a rainforest or two for the filter though

&lt;/div&gt;

&lt;div&gt;

\[4\] Nationals recently passed a motion to block any mandatory Internet filtering

&lt;/div&gt;

&lt;div&gt;

\[5\] PPAU by definition has to block the filter.

&lt;/div&gt;</content><category term="posts"/><category term="rant"/><category term="politics"/><category term="australia"/><category term="IRL"/><category term="censorship"/></entry><entry><title>Ben NanoNote First Impressions</title><link href="/ben-nanonote-first-impressions.html" rel="alternate"/><published>2010-06-15T07:22:00+10:00</published><updated>2010-06-15T07:22:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-06-15:/ben-nanonote-first-impressions.html</id><summary type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="http://farm2.static.flickr.com/1270/4702037485_a9f9cb2b68_b.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="http://farm2.static.flickr.com/1270/4702037485_a9f9cb2b68_b.jpg" data-border="0" width="320" height="213" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Recently unboxed my &lt;a href="http://nanonote.cc/"&gt;Ben NanoNote&lt;/a&gt;, and I am impressed. The packaging was top-notch and classy as hell. I would not hesitate to put my name to it.  &lt;/p&gt;
&lt;p&gt;The NanoNote itself is tiny, and feels fairly solid despite the shiny-appearance which I have come to associate with cheapo devices. It's a …&lt;/p&gt;</summary><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;

&lt;a href="http://farm2.static.flickr.com/1270/4702037485_a9f9cb2b68_b.jpg" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img src="http://farm2.static.flickr.com/1270/4702037485_a9f9cb2b68_b.jpg" data-border="0" width="320" height="213" /&gt;&lt;/a&gt;

&lt;/div&gt;

&lt;p&gt;Recently unboxed my &lt;a href="http://nanonote.cc/"&gt;Ben NanoNote&lt;/a&gt;, and I am impressed. The packaging was top-notch and classy as hell. I would not hesitate to put my name to it.  &lt;/p&gt;
&lt;p&gt;The NanoNote itself is tiny, and feels fairly solid despite the shiny-appearance which I have come to associate with cheapo devices. It's a nice little package, the only issue being the lack of cover of some sort for the micro-SD card slot, which is odd considering the USB port does.  &lt;/p&gt;
&lt;p&gt;For those wondering, the keyboard has good tactile feedback, though there is no way you are touch typing on this.  &lt;/p&gt;
&lt;p&gt;&lt;a href="http://farm5.static.flickr.com/4010/4702669824_353a2bf43a_b.jpg" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img src="http://farm5.static.flickr.com/4010/4702669824_353a2bf43a_b.jpg" data-border="0" width="320" height="213" /&gt;&lt;/a&gt;There is a microphone opening and a speaker grill, though I have no at this time exercised any of those functions.  &lt;/p&gt;
&lt;p&gt;If you are wondering what the Ben NanoNote is, here is a little background:  &lt;/p&gt;
&lt;p&gt;Ben NanoNote is a \$99 device which runs OpenWRT. In and of itself this is nothing special. What is special is the copyleft hardware - you can download the schematics off &lt;a href="http://en.qi-hardware.com/wiki/Main_Page"&gt;qi-hardware&lt;/a&gt;. For hardware meddlers like myself, this is a boon: we can do many interesting things when we know exactly what is available to us and how.  &lt;/p&gt;
&lt;p&gt;The copyleft nature of the NanoNote hardware is that anyone else can build their own 100% compatible NanoNote variant. This allows immediately opens the platform to competition, and it also gives product developers peace-of-mind: you can always make your own Ben NanoNote, even if qi-hardware stops making them.  &lt;/p&gt;
&lt;p&gt;In many ways, the Ben NanoNote is like the arduino: here is some hardware and schematics along with a software platform/SDK with source. Now go wild.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/><category term="electronics"/><category term="IRL"/><category term="oss"/><category term="linux"/></entry><entry><title>Open Letter to Silicon Chip Australia</title><link href="/open-letter-to-silicon-chip-australia.html" rel="alternate"/><published>2010-06-15T06:53:00+10:00</published><updated>2010-06-15T06:53:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-06-15:/open-letter-to-silicon-chip-australia.html</id><summary type="html">&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;
Dear Silicon Chip,  &lt;/p&gt;
&lt;p&gt;I recently cancelled my print subscription. You are no longer a magazine I wish to support.  &lt;/p&gt;
&lt;p&gt;Political commentary on topics like the insulation scheme and global warming has no place in an electronics magazine. The editor(s) are using the mailbag section to push their own agendas …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Lucida Grande'; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;
Dear Silicon Chip,  &lt;/p&gt;
&lt;p&gt;I recently cancelled my print subscription. You are no longer a magazine I wish to support.  &lt;/p&gt;
&lt;p&gt;Political commentary on topics like the insulation scheme and global warming has no place in an electronics magazine. The editor(s) are using the mailbag section to push their own agendas and opinions on the rest of us. I can no longer tolerate such non-sense, and have no interest in financially supporting a magazine that is so set on disinformation and irrational discourse.  &lt;/p&gt;
&lt;p&gt;Let me be clear: I am not cancelling my subscription because of the beliefs of the people at SC. I am cancelling because SC is being used as a platform to spread those beliefs. Whether or not SC believes in global warming, or that the government is at fault for the deaths from the insulation scheme, commentary of these issues are best left to newspapers. They have no place in a publication about electronics.  &lt;/p&gt;
&lt;p&gt;On other thing, the filler article reviewing consumer electronics (e.g. MacBook) is most annoying. It lowers the standard of the magazine. If you really have nothing to write about, go find some interesting arduino variants, like the jeeNode, and review one of those.  &lt;/p&gt;
&lt;p&gt;You have lost your way SC, and it is a sad thing to have to let you go. Maybe we can get back together again.  &lt;/p&gt;
&lt;div&gt;

Steve

&lt;/div&gt;</content><category term="posts"/><category term="rant"/><category term="politics"/><category term="IRL"/><category term="electronics"/></entry><entry><title>Script to make IPAs for ad-hoc distribution.</title><link href="/script-to-make-ipas-for-ad-hoc-distribution.html" rel="alternate"/><published>2010-06-09T05:22:00+10:00</published><updated>2010-06-09T05:22:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-06-09:/script-to-make-ipas-for-ad-hoc-distribution.html</id><summary type="html">&lt;p&gt;This script produces an IPA, then verifies to make sure the IPA is actually valid.  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PRODUCT_NAME=""&lt;br&gt;
IPA="\&lt;span PRODUCT_NAME class="math"&gt;\({PRODUCT_NAME}.ipa"  
APP="\\)&lt;/span&gt;.app"  &lt;/p&gt;
&lt;p&gt;if [ -z "\${PRODUCT_NAME}" ]; then&lt;br&gt;
        echo "PRODUCT_NAME not set";&lt;br&gt;
        exit 1;&lt;br&gt;
fi  &lt;/p&gt;
&lt;p&gt;rm -rf ipa&lt;br&gt;
mkdir -p ipa/Payload &amp;amp;&amp;amp;&lt;br&gt;
cp -R build/Debug-iphoneos/\&lt;span IPA class="math"&gt;\({APP} ipa/Payload/ &amp;amp;&amp;amp;  
pushd ipa &amp;amp;&amp;amp;  
zip -q …&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;This script produces an IPA, then verifies to make sure the IPA is actually valid.  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PRODUCT_NAME=""&lt;br&gt;
IPA="\&lt;span PRODUCT_NAME class="math"&gt;\({PRODUCT_NAME}.ipa"  
APP="\\)&lt;/span&gt;.app"  &lt;/p&gt;
&lt;p&gt;if [ -z "\${PRODUCT_NAME}" ]; then&lt;br&gt;
        echo "PRODUCT_NAME not set";&lt;br&gt;
        exit 1;&lt;br&gt;
fi  &lt;/p&gt;
&lt;p&gt;rm -rf ipa&lt;br&gt;
mkdir -p ipa/Payload &amp;amp;&amp;amp;&lt;br&gt;
cp -R build/Debug-iphoneos/\&lt;span IPA class="math"&gt;\({APP} ipa/Payload/ &amp;amp;&amp;amp;  
pushd ipa &amp;amp;&amp;amp;  
zip -q --symlinks -r \\)&lt;/span&gt; Payload/ &amp;amp;&amp;amp;&lt;br&gt;
mkdir test/ &amp;amp;&amp;amp;&lt;br&gt;
cp \&lt;span IPA class="math"&gt;\({IPA} test &amp;amp;&amp;amp;  
cd test &amp;amp;&amp;amp;  
unzip -q \\)&lt;/span&gt; &amp;amp;&amp;amp;&lt;br&gt;
cd Payload/ &amp;amp;&amp;amp;&lt;br&gt;
codesign --verify --verbose \${APP} &amp;amp;&amp;amp;&lt;br&gt;
popd&lt;br&gt;
open ipa/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Designed to be ran from the command line, but it should be easily made into a build phase.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="posts"/><category term="software"/><category term="code"/></entry><entry><title>2010-06-09</title><link href="/2010-06-09.html" rel="alternate"/><published>2010-06-09T04:35:00+10:00</published><updated>2010-06-09T04:35:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-06-09:/2010-06-09.html</id><summary type="html">&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;PRODUCT_NAME=""&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IPA="\&lt;span PRODUCT_NAME class="math"&gt;\({PRODUCT_NAME}.ipa"&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;APP="\\)&lt;/span&gt;.app"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if [ -z "\&lt;span APP class="math"&gt;\({PRODUCT_NAME}" \]; then&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;        echo "PRODUCT_NAME not set";&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;        exit 1;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span …&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;PRODUCT_NAME=""&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;IPA="\&lt;span PRODUCT_NAME class="math"&gt;\({PRODUCT_NAME}.ipa"&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;APP="\\)&lt;/span&gt;.app"&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;if [ -z "\&lt;span APP class="math"&gt;\({PRODUCT_NAME}" \]; then&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;        echo "PRODUCT_NAME not set";&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;        exit 1;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;fi&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;  
&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;rm -rf ipa&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;mkdir -p ipa/Payload &amp;amp;&amp;amp;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;cp -R build/Debug-iphoneos/\\)&lt;/span&gt; ipa/Payload/ &amp;amp;&amp;amp;&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pushd ipa &amp;amp;&amp;amp;&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;zip -q --symlinks -r \&lt;span IPA class="math"&gt;\({IPA} Payload/ &amp;amp;&amp;amp;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;mkdir test/ &amp;amp;&amp;amp;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;cp \\)&lt;/span&gt; test &amp;amp;&amp;amp;&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cd test &amp;amp;&amp;amp;&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;unzip -q \&lt;span APP class="math"&gt;\({IPA} &amp;amp;&amp;amp;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;cd Payload/ &amp;amp;&amp;amp;&amp;lt;/span&amp;gt;  
&amp;lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&amp;gt;codesign --verify --verbose \\)&lt;/span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;popd&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;open ipa/&lt;/span&gt;&lt;br&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br&gt;
&lt;/span&gt;  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;
&lt;script type="text/javascript"&gt;if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
    var align = "center",
        indent = "0em",
        linebreak = "false";

    if (false) {
        align = (screen.width &lt; 768) ? "left" : align;
        indent = (screen.width &lt; 768) ? "0em" : indent;
        linebreak = (screen.width &lt; 768) ? 'true' : linebreak;
    }

    var mathjaxscript = document.createElement('script');
    mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
    mathjaxscript.type = 'text/javascript';
    mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';

    var configscript = document.createElement('script');
    configscript.type = 'text/x-mathjax-config';
    configscript[(window.opera ? "innerHTML" : "text")] =
        "MathJax.Hub.Config({" +
        "    config: ['MMLorHTML.js']," +
        "    TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
        "    jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
        "    extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
        "    displayAlign: '"+ align +"'," +
        "    displayIndent: '"+ indent +"'," +
        "    showMathMenu: true," +
        "    messageStyle: 'normal'," +
        "    tex2jax: { " +
        "        inlineMath: [ ['\\\\(','\\\\)'] ], " +
        "        displayMath: [ ['$$','$$'] ]," +
        "        processEscapes: true," +
        "        preview: 'TeX'," +
        "    }, " +
        "    'HTML-CSS': { " +
        "        availableFonts: ['STIX', 'TeX']," +
        "        preferredFont: 'STIX'," +
        "        styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
        "        linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
        "    }, " +
        "}); " +
        "if ('default' !== 'default') {" +
            "MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
            "MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
                "var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
                "VARIANT['normal'].fonts.unshift('MathJax_default');" +
                "VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
                "VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
                "VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
            "});" +
        "}";

    (document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
    (document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
&lt;/script&gt;</content><category term="posts"/></entry><entry><title>Discouraging File Sharers at LANs</title><link href="/discouraging-file-sharers-at-lans.html" rel="alternate"/><published>2010-05-08T07:58:00+10:00</published><updated>2010-05-08T07:58:00+10:00</updated><author><name>Steve</name></author><id>tag:None,2010-05-08:/discouraging-file-sharers-at-lans.html</id><summary type="html">&lt;p&gt;A friend of mine likes to go to LANs and like to run LANs. He has been complaining for sometime that social gaming no longer occur at LANs and in its place is leeching. Lest you think LANs have somehow turned into 19th century medical clinics, we are talking about …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A friend of mine likes to go to LANs and like to run LANs. He has been complaining for sometime that social gaming no longer occur at LANs and in its place is leeching. Lest you think LANs have somehow turned into 19th century medical clinics, we are talking about leeching of files, which given the kind of people who go to LANs, consists of porn, porn, porn, movie, and porn.  &lt;/p&gt;
&lt;p&gt;My friend laments that he hasn't found a nice way to deal with file sharers such gamers aren't impacted, since some file sharing is required for games installers, updaters, drivers, etc. Any kind of port blocking, packet inspection, real-life-what-are-you-doing inspection are right out for the reasons of impotency, latency, and privacy.  &lt;/p&gt;
&lt;p&gt;After some discussion, we came up on the following idea to discourage, not ban, file sharers: limit upload rate of all ports. This won't affect 99.99% of gamers since games use very little bandwidth, and it still lets you download at full speed. This however impacts significantly on file sharers: the theoretical maximum downstream a file sharer can achieve is n-1 * upload_rate, which assumes everyone else is giving him their upstream bandwidth. Make this theoretical maximum low enough, and file sharers are better off using sneaker net.  &lt;/p&gt;
&lt;p&gt;There is an elegance to this that appeals to me - it exploits the fact gaming prioritise latency over bandwidth, and file sharing bandwidth over latency. It is also resistant to circumvention -  because this can be implemented on the data link layer, it isn't something file sharers can get around by changing ports or using encryption.  &lt;/p&gt;
&lt;p&gt;If you know of any LANs that implement this policy, or run a LAN implementing this policy, I would love to know how well this idea performs in the real world.  &lt;/p&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="computer"/></entry><entry><title>Notes on PHD Guiding</title><link href="/notes-on-phd-guiding.html" rel="alternate"/><published>2010-03-26T02:45:00+11:00</published><updated>2010-03-26T02:45:00+11:00</updated><author><name>Steve</name></author><id>tag:None,2010-03-26:/notes-on-phd-guiding.html</id><summary type="html">&lt;ul&gt;
&lt;li&gt;Maximum RA guide pulse is 1000ms (1s). If PHD is not locking on to the star and it says "dur=1000" in the status bar, a better polar alignment is required.&lt;/li&gt;
&lt;li&gt;RA hysteresis is used in a 2-term weighted moving average:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;RA_dist = (1.0 - RA_hysteresis) * RA_dist + RA_hysteresis * last_guide&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve …&lt;/p&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;Maximum RA guide pulse is 1000ms (1s). If PHD is not locking on to the star and it says "dur=1000" in the status bar, a better polar alignment is required.&lt;/li&gt;
&lt;li&gt;RA hysteresis is used in a 2-term weighted moving average:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;RA_dist = (1.0 - RA_hysteresis) * RA_dist + RA_hysteresis * last_guide&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cheers,&lt;br&gt;
Steve&lt;/p&gt;</content><category term="posts"/><category term="astronomy"/><category term="code"/></entry></feed>