środa, 27 marca 2013

LaTeX: example of a complex titlepage design

Let's start from example preamble:


\documentclass[twoside]{article}
\usepackage{fancyhdr}

\pagestyle{fancy}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}

\makeatletter
%% headlines (\@shorttitle/\@shortauthorlist see below):
\fancyhead[RO]{\@shorttitle}
\fancyhead[LE]{\@shortauthorlist}

...
\makeatother

% Title (in Polish) and alternate title (in english):
\title{Hemofiltracja i~rewaskularyzacja u~pacjenta
z~zespołem sercowo-nerkowym typu 2}
\alttitle{Hemofiltration in patient with cardio-renal syndrome type 2}

% Authors list:
\author{WLUJ}{Janina Kowalska }
\author{CIL}{Zofia Dyrman}
\author{KCW}{Andrzej Jarzyna}
\author{CIL}{Wacław Jarząbek}
\author{CIL}{Krzysztof Chrostowicz}
% Undefined affiliation raises an error:
% \author{DoPX}{Zdzisław Dyrman}

% Affliations list:
\affiliation{WLUJ}{Wydział Lekarski Uniwersytetu Jagiellońskiego
-- Collegium Medicum, ul.~św.~Anny 12, 31--008 Kraków}
\affiliation{CIL}{Centrum Interwencyjnego Leczenia Chorób Serca
i~Naczyń, KSzS im.~Jana Pawła II, ul. Prądnicka 80, 31--202 Kraków}
\affiliation{KCW}{Klinika Choroby Wieńcowej UJ, Collegium Medicum,
KSzS im. Jana Pawła II, ul. Prądnicka 80, 31--202 Kraków}
% Extra affiliation raises an error:
% \affiliation{DRS}{Druskienniki, Pendological Department}

% Short versions of title/authors list (defined if title/authors list
% is too long to fit the headlines:
% \shortauthor{Tratata}
% \shorttitle{Fififif}
%
\begin{document}
\maketitle

\end{document}
LaTeX example titlepage
The titlepage

The main problem is long lists of authors and affiliations. There are more authors than affiliations so affiliations are labelled with consecutive numbers and each author is marked with appropriate label indicating his/her affiliation. It can be done manually of course but with the help of a few clever macros the numbers can be computed by LaTeX. This feature can be particularly helpful when for instance just before the (printing house) deadline a very important author (probably professor) insists his affiliation should be 1 not 4 (for example). All is needed to achieve this is to reorder \affiliation declarations.

The resulting document looks like shown in the picture.

The macros used:


%++Authors and affiliations
\newcount \authornumber
\newcount \affiliationnumber
\authornumber=0
\affiliationnumber = 0
%
\def\alttitle#1{\gdef\@alttitle{#1}}%
\def\shortalttitle#1{\gdef\@shortalttitle{#1}}

\def\author#1#2{%
\global\advance\authornumber\@ne
\authorAffiliationId{#1}% -- label --
\authorName{#2}% -- author's name --
}
%
\def\authorAffiliationId#1{%
\expandafter\def\csname theauthorid\number%
\authornumber\endcsname {#1}% --author's id--
%% label defined to check if affiliation exists:--
\expandafter\def\csname theaffid:#1\endcsname {#1}%
}
%
\def\authorName#1{%
\expandafter\def\csname theauthor\number%
\authornumber\endcsname{\ignorespaces#1\unskip}%
\expandafter\let\csname theauthoraffiliation\number%
\authornumber\endcsname\relax
}
%
\def\affiliation#1#2{%
\global\advance\affiliationnumber\@ne
\expandafter\def\csname theaffiliation \number%
\affiliationnumber \endcsname {\ignorespaces#2\unskip}%
\expandafter\edef\csname affid:#1\endcsname {\number\affiliationnumber}%
%% if defined in class CLS add error mesage:
%%\@ifundefined{theaffid:#1}{\ClassError{CLS}{**Affiliation undefined: `#1'}\@ehc}{}%
}
%
\def\@author{\@defaultauthorlist}
\def\@affiliation{\@defaultaffiliationlist}
%
\newcount\count@@
%
% Authors/affiliations lists
\def\@defaultauthorlist{%
\count@=\authornumber
\count@@=0
\begingroup
\loop
\ifnum\count@>0
\advance\count@@ by 1
\ignorespaces\csname theauthor\number%%
\count@@\endcsname %-- autor's name --
\edef\@TmP@Aff@Etykieta{\csname theauthorid\number\count@@ \endcsname}%
% --check if \@TmP@Aff@Etykieta exists: --
\@ifundefined{affid:\@TmP@Aff@Etykieta}%
%% if defined in class CLS add error mesage:
%%{\ClassError{CLS}{**Brak afiliacji dla \csname theauthor\number%
%%\count@@\endcsname}\@ehc}%
%% print out affiliation label (number):
{$^{\csname affid:\@TmP@Aff@Etykieta\endcsname}$}%
%--Every author but last is separated by a comma--:
\ifnum\count@=1\relax\else,\space\fi
\advance\count@ by -1
\repeat
\endgroup
}
% Short list of authors (w/o affiliations labels) for headlines.
% Simplified version of @defaultauthorlist:
\def\@defaultshortauthorlist{%
\count@=\authornumber
\count@@=0
\begingroup
\loop
\ifnum\count@>0
\advance\count@@ by 1
\ignorespaces\csname theauthor\number\count@@\endcsname
\ifnum\count@=1\relax\else,\space\fi
\advance\count@ by -1
\repeat
\endgroup
}
%
% Affilitions list:
\def\@defaultaffiliationlist{%
\count@=\affiliationnumber
\count@@=0
\begingroup
\loop
\ifnum\count@>0
\advance\count@@ by 1
$^{\the\count@@}$ %-- affiliation number
%-- print out the affiliation:
\ignorespaces\csname theaffiliation \number\count@@\endcsname
% ++Every affiliation but last is separated by a comma ++ :
\ifnum\count@=1\relax\else,\space\fi
% każda afiliacja od nowego wiersza:
\par
\advance\count@ by -1
\repeat
\endgroup
}
% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
% ++SIMPLIFIED titlepage (just to demonstrate macros defined):++
\renewcommand\maketitle{%
\begin{titlepage}%
\let\footnotesize\small
\let\footnoterule\relax
\let \footnote \thanks
% ++Title: ++
\parindent0pt
\rightskip0pt plus 4em \pretolerance10001
\leavevmode \noindent
{\Large \sffamily \bfseries
\@title\par
% ++ Optional alternative title:
\@ifundefined{@alttitle}{}{\vskip9pt%
\large \sffamily \bfseries \@alttitle \par} }
\vspace{5mm}
% ++Authors list:
{\rightskip 0pt plus6em%
\@author\par}
%
\vspace{30pt}
% ++Affiliations list
{\rightskip 0pt plus6em \@affiliation\par}
%
% ++Define content for running headers/footers:
\@ifundefined{@shortauthorlist}{\gdef\@shortauthorlist{\@defaultshortauthorlist}}{}%
\@ifundefined{@shorttitle}{\gdef\@shorttitle{\@title}}{}%
\@ifundefined{@shortalttitle}{\gdef\@shortalttitle{\@alttitle}}{}%
%
\thispagestyle{empty}
\end{titlepage}%
%
\setcounter{footnote}{0}%
\global\let\thanks\relax
\global\let\maketitle\relax
\global\let\@thanks\@empty
\global\let\title\relax
\global\let\author\relax
\global\let\date\relax
\global\let\and\relax
}%%//maketitle//

\def\shorttitle#1{\gdef\@shorttitle{#1}}
\def\shortauthorlist#1{\gdef\@shortauthorlist{#1}}
\let\shortauthor\shortauthorlist

wtorek, 26 marca 2013

LaTeX: how to highlight some bibliography entries by adding an asterisk before the entry?

Author-year citation style is assumed.

If a bibliography is prepared manually it is as easy as to precede each entry with say \bibAst command. Example:

\newcommand\bibAst{\leavevmode\hbox to0pt{\hss$^\ast$}}

\harvarditem[Bagozzi and Dholakia]{Bagozzi and
Dholakia}{2006}{bagozzidholakia06}
\bibAst\textsc{Bagozzi, R.~P., {\small and} U.~M. Dholakia} (2006): ``Open
Source Software User Communities: A Study Of Participation In {L}inux {U}ser
{G}roups,'' \emph{Management Science}, 52(7), 1099--1115.

If one insists on using BiBTeX one has to mark records which are to be highlighted. It can be done with an extra field (named highlight in the example below):


@Article{bagozzidholakia06,
title = "Open Source Software User Communities: A Study Of
Participation In {L}inux {U}ser {G}roups",
author = "Bagozzi, Richard P. and Dholakia, Utpal M.",
journal = j-msci,
pages = "1099--1115",
number = "7",
volume = "52",
year = "2006",
highlight = "Y"
}

Fields unknown to BiBTeX's particular style are omitted, so highlight cause no harm when processed with standard BiBTeX style.

One need to modify BiBTeX style now. This is a two-step procedure. First one has to add highlight to the body of ENTRY function:


ENTRY
{
...
highlight
}

Next one has to modify format.authors function. Exact form of a format.authors function is style-dependent. In case of apalike the code looks like:


%FUNCTION {format.authors}
%{ author empty$
% { "" }
% { author format.names }
% if$
%}
% change to:
FUNCTION {format.authors}
{ author empty$
{ "" }
{ highlight empty$
{ author format.names }
{ "{\bibAst}" author format.names * }
if$
}
if$
}

BTW: the meaning of some BiBTeX expressions are as follows: S1 S2 * denotes S1 S2 strings concatenation; L F1 F2 if$ denotes logical if (execute F1 if L is true otherwise execute F2).

The contents of highlight is irrelevant. Sole existence of highlight denotes that the record is highlighted.

NOTE: the style should be more elaborate if some BiBTeX entries starts with something other than authors names.

piątek, 22 marca 2013

Automatic SMS Alerts Using Google Calendar

The idea is to add an event to Google calendar with some short start time from now (say 15 minutes) and SMS reminder feature.


#!/bin/bash
# reminder via google with 15 minutes from now start time
#
MESSAGE="Neptune ALARM: something nasty has happened!"

# In case of service failure try 3 times:
for i in 1 2 3; do

# Compute 15min from now time with date:
NOW=`date "+%s"`
TIME_SHF1=$(($NOW + 900 ))
FWD_TIME1=`date +"%d/%m/%Y %H:%M" -d"@$TIME_SHF1"`;

# Check for optional script argument
if [ -n "$1" ] ; then MESSAGE="Neptune ALARM: $1" ; fi

# use GoogleCL to add to calendar with 15m from now/1m reminder
google calendar add "$MESSAGE $FWD_TIME1" --reminder="1m"

RC=$?

if [ $RC -ne 0 ] ; then
sleep 30;
else
break ;
fi

done

The script uses GoogleCL (a python-based command-line utility for accessing Google). Installing GoogleCL is easy:


sudo apt-get install googlecl
# or (in case there is no ready-to install package):
wget http://googlecl.googlecode.com/files/googlecl-0.9.13.tar.gz
tar -zxvf googlecl-0.9.13.tar.gz
cd googlecl-0.9.13
sudo python setup.py install

Note: googleCL is launched via google not googleCL command.

The first time one uses googleCL, ie:


google calendar add "test from neptune 22/03/2013 10:30:22"

it will prompt for one's Google username. One has to type it in and hit enter. Next the user is asked to grant access permissions.

On non-gui systems (text-based) w3m browser usually will be launched. When connected to google one has to press q y and the text silimlar to the following will be displayed:


Please log in and/or grant access via your browser
at https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=\
4%xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&hd=default then hit enter.

One has to copy the above link to another machine (with gui browser). Next one has to grant access and then go back to the terminal and hit enter to complete the authorization.

BTW the access token is stored in:


~/.local/share/googlecl/access_tok_USERNAME

If access is granted from some machine it will probably suffice to copy the access token file to another machine to grant access for it as well (not tested).

The configuration file for googleCL is in:


~/.config/googlecl

If access is grated successfully the message similar to the following will be displayed:


Event created: http://www.google.com/calendar/event?eid=\ anFsdGFucXFwdmZnbW1sMmcwc2t1NDI3cm8gbG9vc2VoZWFkcHJvcDFAbQ

piątek, 15 marca 2013

LaTeX: znaki cięcia/pasery, pakiety crop i fancyhdr

Kol. WP dba żebym nie wyszedł z wprawy w temacie znajomości LaTeXa.

Jakiś czas temu zażyczył sobie znaków cięcia (zwanych także paserami). Znaki cięcia mają określać wielkość kartki papieru jako 290x205mm (prawie A4). Mają być umieszczone na stronie o nietypowych wymiarach 330x250mm.

Używając pakietu crop można powyższe zalecenie zrealizować następująco:


\documentclass{article}

%% Inne pakiety dołączyć tutaj ...

\setlength\paperheight {290mm}\setlength\paperwidth{205mm}
\usepackage[cam,center,width=250truemm,height=330truemm,pdftex]{crop}
%%
%% Kolumna ma być wyśrodkowana na kartce (zalecenie drukarni)
%% Margines wynosi ( \paperwidth -\textwidth )/2
\oddsidemargin 18.5truemm %% dla \textwidth = 168mm
\evensidemargin\oddsidemargin

\begin{document}

...

\end{document}

No i działa. Dokument jest składany XeTeXem; używa w związku z tym pakietów polyglossia, fontspec, xunicode oraz xltxtra. Powyższe pakiety korzystają z kolei ze stada pakietów z l3kernel/l3packages bundles (fragment przyszłej, ciągle tworzonej od 20 bodajże lat, trzeciej wersji LaTeXa -- LaTeX3 project).

Po jakimś czasie okazało się, że nie działa w MikTeX 2.09. Pierwsza (tytułowa) strona jest podniesiona (względem znaków cięcia) o ok 4mm w porównaniu do wszystkich następnych.

Po dłuższym badaniu stwierdzono, że winna jest dwuwierszowa pagina górna znajdująca się na stronie tytułowej. Wydawała się niegroźna i co więcej, dokument był poprawnie kompilowany, ale tylko w dystrybucji TL 2011. Coś zmieniono w zestawie pakietów l3* (których jest dużo jak wiemy) i to te pakiety odpowiadają za błąd.

Żeby obejść problem postanowiłem składać dwuwierszową paginę w pudełko pionowe (\vbox) o wysokości równej wysokości wiersza tekstu:


\setbox0\hbox{\PM@HeaderFont\strut} %%
\newdimen\PM@HeaderHt \PM@HeaderHt=\ht0
\def\PM@vboxToOneLine#1{\vbox to\PM@HeaderHt{#1\vss}}
%% ^^^^^^^ pudełko o wysokości wiersza tekstu ^^
%% %% ...
\fancypagestyle{plain}{%% zawartość paginy na stronie tytułowej:
\fancyhf{} %
%% ...
\fancyhead[L]{\leavevmode
\hbox{\PM@vboxToOneLine{\PM@HeaderFont pierwszy-wiersz ... \\
... drugi wiersz ...}}} %
\fancyhead[R]{\leavevmode
\hbox{\PM@vboxToOneLine{\PM@HeaderFont pierwszy-wiersz ... \\
... drugi wiersz ...}}}
%% ...
}

Teraz działa lepiej.

Nawiasem mówiąc dwuwierszowe paginy to kiepski pomysł. W szczególności fancyhdr wyrównuje górne wiersze pagin, co oznacza, że np. kreska pod paginą będzie nie wyrównana jeżeli (przykładowo) lewa pagina jest dwuwierszowa a prawa jednowierszowa. W omawianym przypadku nie ma kreski pod paginą, dwuwierszowa pagina jest zdefiniowana wyłącznie na stronie tytułowej (której układ jest znakomicie różny od pozostałych stron) a i tak skończyło się problemem.

środa, 6 marca 2013

Raspberry Pi: first steps with time-lapse photography

A620 powered with CA-PS500 adapter
A620 powered with CA-PS500
A620 with improvised sun cover
A620 (side view)

I would like to remote control a still camera via gphoto2. After consulting a  list of supported cameras I bought (used) Canon A620 from Allegro (local Internet auction site, sort of E-bay).

This camera has many great features (I suspect even too great as Canon stop producing cheap cameras of this sort): viewfinder, retractable LCD and can be powered with Compact Power Adapter CA-PS500 instead of batteries (an important feature in my project). The plan was simple: connect camera via USB cable to computer and power it with PSU. Capture photos periodically with gphoto2:


gphoto2 --auto-detect

pi@raspberrystar ~/bin $ gphoto2 --auto-detect
Model Port
----------------------------------------------------------
Canon PowerShot A620 (PTP mode) usb:001,006

So far, so good.

Now, I tried to capture a photo:


# one shot without flash, download the file and store in a file named as: GPHyyyymmddhhmm.jpg
LANG=C gphoto2 --set-config flashmode=0 --capture-image-and-download --filename "GPH%Y%m%d%H%M.jpg"

As the creation time is wrong (due to camera wrong clock) I modified the above as follows (note that touch is used to adjust file's timestamp):


#!/bin/bash
FILENAME="GPH`date +"%Y%m%d%H%M"`.jpg"

LANG=C gphoto2 --set-config flashmode=0 --capture-image-and-download --filename "$FILENAME"
touch "$FILENAME"

Unfortunately there are problems: I am able to remotely capture only one photo. Next remote capture try results in an error and the camera has to be hard reset (with power on/off button). The problem is reported by others too.

BTW: when I connected the camera to my PC the reliability is much better (but seems not perfect---I experienced camera disconnection too.)

My first try to resolve the problems was to update gphoto2 (raspbian contains version 2.4.14 of gphoto2).

Compiling newest (march 2013) version of gphoto2 on Raspberry Pi


## optionally remove old version (there are no dependencies)
apt-get remove gphoto2

There is no need to remove gphoto2 as compiled one will be installed in another directory (/usr/local/ vs /usr/).

First install/compile the necessary packages:


apt-get install -y libltdl-dev libusb-dev libexif-dev libpopt-dev

## Download and install newer version of libusb 1.0.11
wget http://ftp.de.debian.org/debian/pool/main/libu/libusbx/libusbx_1.0.11.orig.tar.bz2
tar xjvf libusbx_1.0.11.orig.tar.bz2
cd libusbx-1.0.11/

./configure && make && sudo make install

## Download and install newer version of libgphoto
wget http://garr.dl.sourceforge.net/project/gphoto/libgphoto/2.5.1.1/libgphoto2-2.5.1.1.tar.bz2
tar xjf libgphoto2-2.5.1.1.tar.bz2
cd libgphoto2-2.5.1.1

./configure && make && sudo make install

Download and install newer version of gphoto2


wget http://downloads.sourceforge.net/project/gphoto/gphoto/2.5.1/gphoto2-2.5.1.tar.gz
tar xzvf gphoto2-2.5.1.tar.gz
cd gphoto2-2.5.1

./configure && make && sudo make install

## run ldconfig
sudo ldconfig
gphoto2 --version
gphoto2 2.5.1

Copyright (c) 2000-2013 Lutz Mueller i inni

BTW compiling gphoto2 on my fedora 14 box requires to install libtool-ltdl-devel popt-devel first:


#configure: error: cannot compile and link against libltdl
#libgphoto2 requires libltdl (the libtool dl* library),
#but cannot compile and link against it.

yum -y install libtool-ltdl-devel popt-devel

Upon installing above two packages, the compilation of libusb, libgphoto and gphoto2 proceeds smoothly.

Unfortunately installing new version of gphoto2 did not help.

The problem will be further examined...

Video geocoding with gpsbabel

contour camera mounted at bike frame
Contour camera

NOTE: This post is (partially) obsolete as I prefer `visual correlation' method now (see my newer post.)

Some time ago I bought a Contour HD camera on Ebay and the seller claimed he was selling it as he want to upgrade to GPS enabled model. That inspired me to investigate how I can do the same with the camera lacking build-in GPS receiver. For example to geotag photos one can use GPS enabled still cameras, but usually it is a costly luxury and it suffice to synchronize GPS log with a photo timestamp. Using this approach I have developed a simple bash scripts which works neatly with all my cameras. So I can geotag my photographs without wasting a lot of time.

In case of video images the approach is similar: one has to synchronize video and GPS data. The best approach is to film the display of the GPS unit showing the GPS time. In case when the camera is unable to get a good quality image (because the digits are too small for example as in case of my Garmin Legend) a simple trick can be used: just one has to write down time on a sheet of paper (using 15-30 seconds time-ahead) and in a appropriate moment film it. Or one can says out loudly the time displayed if the microphone is able to record it. Looks silly and old fashioned but works. Instead of the above two methods one have to establish initial video geolocation with `visual correlation' method (described in the next paragraph).

The camera Pause button should not be used as it breaks out the GPS-camera synchronization. Namely after every pause one has to establish correct initial geolocation which can be difficult but not impossible (`visual correlation' can be used ie. inspecting video for distinguishable objects which geo-position can be established). I think the advantage of GPS-equipped camcorder boils down to that aspect (one can use Pause w/o worrying that his/her video will be out of sync.) but I suspect to take this extra advantage some extra software is needed which almost for sure runs on MS Windows. For a Linux users it can be usless or at least troublesome.

The only method I tried to augment video files with GPS data is to convert them to video subtitles. Since version 1.4 of GPSBabel is able to create a subtitle file from a GPS tracklog. The subtitle contains latitude/longitude/altitude as well as the time and current speed.

To convert GPX file to subtitles one have to execute:


gpsbabel -i gpx -f FILE.gpx -o subrip,video_time=hhmmss,gps_time=hhmmss,gps_date=YYYYMMDD -F FILE.srt

Where: video_time -- video position (relative to beginning of video) for which exact corresponding GPS timestamp is known. gps_time -- the time part of the GPS timestamp which corresponds to a known position in the video. gps_date -- the date part of the GPS timestamp which corresponds to a known position in the video.

Let's assume that the recorded image of GPS display appears in 15 second of the captured image. One has to look for (inside GPX file) the timestamp containing the exact time displayed (element <time> inside element <trkpt>). Let's assume this timestamp is <time>2013-02-07T09:58:29Z</time>. To convert GPX to subtitles one has to run:


gpsbabel -i gpx -f FILE.gpx -o subrip,video_time=000015,gps_time=095829,gps_date=20130207 -F FILE.srt

Just to remind: internally all GPS units record time/date using Coordinated Universal Time aka Greenwich Mean Time vel Zulu time (for army enthusiasts). What the unit displays is another matter (usually it displays local time).

My first geotagged video obtained using method described above can be seen here.