Как построить графики с погрешностями в gnuplot по экспериментальным данным



17 коммент.
Собственно, наиболее часто в экспериментальной физике требуется строить графики, которые отражают точность измерений - на графиках требуется откладывать погрешности. Так как чаще всего данные организованы в таблицы, построить график с погрешностями в gnuplot нетрудно, однако в этом деле есть ряд подводных камней, о чём ниже.

Для того, чтобы указать gnuplot строить графики с погрешностями, строка с командой plot в скрипте должна содержать директиву with errorbars:
  • погрешности откладываются для данных по оси Х: with xerrorbars
  • погрешности откладываются для данных по оси Y: with yerrorbars
  • погрешности откладываются для данных по обоим осям: with xyerrorbars
Величину погрешности можно посчитать для каждой точки (в зависимости от эксперимента, например, при измерениях на разных пределах) и сделать для этого в файле данных test.dat данных отдельную колонку:
#  X     Y     dX    dY
1.0 1.2 0.8 1.5
2.0 1.8 0.3 2.3
3.0 1.6 1.0 2.1


В этом случае, чтобы построить график с погрешностями по оси Y, например, последняя команда в скрипте для графика будет выглядеть так:
gnuplot> plot "test.dat" using 1:2:3 with yerrorbars
Общая идея, думаю, понятна: сначала указываются колонки, содержащие данные, а потом колонки, содержащие значения погрешностей. Таблица, любезно утянутая отсюда, даёт прекрасную иллюстрацию:

Data Format Columnusing with
(X,Y) data X Y 1:2 lines, points, steps,
linespoints, boxes, etc.
Y has an error of dY X Y dY 1:2:3 yerrorbars
X has an error of dX X Y dX 1:2:3 xerrorbars
Y has an error of dY, and
X has an error of dX
X Y dX dY 1:2:3:4 xyerrorbars
Y has a range of [Y1,Y2] X Y Y1 Y2 1:2:3:4 yerrorbars
X has a range of [X1,X2] X Y X1 X2 1:2:3:4 xerrorbars
Y has a range of [Y1,Y2], and
X has a range of [X1,X2]
X Y X1 X2 Y1 Y2 1:2:3:4:5:6 xyerrorbars


Для иллюстрации разберу два рабочих примера с построением графиков с погрешностями и аппроксимацией данных.


Пример 1. Построить график с погрешностями по обеим осям в gnuplot

Итак, есть экспериментальные данные в виде таблицы с разделителями - пробелами:

16 18 0.72 10 whiteLEDS 1 10
12 30 0.61 12 greenUltraBrightLEDS 1 10
8 200 0.45 20 HGlamp 1 15
6 1600 0.35 35 AlGaAsLser 1 50
4 17000 0.28 68 NdYAG-laser 1 900
4 25000 0.27 70 HeNeLaser 1 1100

Нужно построить зависимость первой колонки от второй, при этом погрешности по оси X составляют 7% от данных, а по оси Y указаны в колонке 7. Вот такой при этом получается код для gnuplot:

#! /usr/bin/gnuplot -persist
set terminal postscript 'NimbusSanL-Regu' eps enhanced
set output "./plot/PSFoutofLambdaDeltaLambdavsfromNumberOfElementsPSF.ps"
set encoding koi8r
set xlabel "Light's monochromaticity, {/Symbol l}/{/Symbol D}{/Symbol l}" font "NimbusSanL-Regu,18"
set nokey
set bmargin 4
set ylabel "Number of resolvable points of the PSF's kinoform" font "NimbusSanL-Regu,18"
set logscale x
set grid
set xrange [1:100000]
set mxtics 10
set style line 1 lt 1 pt 7 ps 0.5
plot "./PSFoutofLambdaDeltaLambda.txt" using 2:((300/$1)**2):7:(((300/$1)**2)*0.07) with xyerrorbars linestyle 1, "./PSFoutofLambdaDeltaLambda.txt" using 2:((300/$1)**2) smooth bezier with lines


Результат строительства графика:
Что в этом коде (и графике) есть примечательного, заставившего меня таки покопаться в мануале?

Ну например то, что при строительстве данных с погрешностями вам не удастся использовать линии: опция with linespoints не пройдёт и gnuplot будет выдавать ошибки. И это правильно: экспериментальные данные соединять непрерывной линией - моветон. Так что используем только linestyle 1 который определён так: set style line 1 lt 1 pt 7 ps 0.5 Это значит: тип линии 1, стиль точек 7, размер точки на графике 0.5. Крайние точки я просто соединил кривой Безье, о чём честно написал в коде графика: smooth bezier with lines

Ну и наконец нужно было построить квадратичную зависимость по оси Y, что реализовано так: ((300/$1)**2) то есть число 300 делится для каждой точки на значение в первой колонке, результат возводится в квадрат.



Пример 2. Построить график с погрешностями и аппроксимацией в gnuplot
Задачка посложнее: здесь требовалось экспериментальные точки аппроксимировать прямой линией и погрешностями. Из части данных нужно вычесть постоянную составляющую, так что работы для gnuplot хватает. Итак, сеанс чёрной магии с полным её разоблачением:

#! /usr/bin/gnuplot -persist
set terminal postscript 'NimbusSanL-Regu' eps enhanced solid
set yrange [0.1:10000]
set logscale x
set logscale y
set mxtics 10
set mytics 10
set grid xtics ytics mxtics mytics
set format y "10^{%L}"
set format x "10^{%L}"
set mxtics 10
set output "./plots/1RAWMEANtoSaturateLineApproxcomparingLogscale.ps"
set encoding koi8r
set xlabel "Exposure value, rel. units" font "NimbusSanL-Regu,18"
set ylabel "Signal mean value, DN" font "NimbusSanL-Regu,18"
set key bottom right
set bmargin 4
set style line 1 lt 2 pt 7 ps 1
f(x) = (a*x)+b
fit f(x) "./RAWMEANmeasurementresult" using 4:($3-255.22579) every ::4::35 via a,b
plot "./RAWMEANmeasurementresult" using 4:($3-255.22579):7 title "Digital values of photosensor signal" with yerrorbars linestyle 1, f(x) title "linear fitting function" with line


Сейчас маэстро Воланд скромный автор сих строк разоблачит этот опыт. Первое, что надо разоблачить - аппроксимацию прямой. Здесь сначала задаётся функция f(x) = (a*x)+b которая далее подгоняется под данные using 4:($3-255.22579) из которых вычитается постоянная величина (эксперимент такой был). Далее при подгонке я потребовал от gnuplot
использовать только точки с 4 по 35-ю every ::4::35 и, наконец, подогнать коэффициенты a и b под данные via a,b.

Здесь я отмечу то, что сам часто забываю: директиву every можно использовать не только при подгонке, но и для других графиков. Для этого полезно иметь перед глазами таблицу, которую изваял автор not so Frequently Asked Questions:

every I:J:K:L:M:N
I Line increment
J Data block increment
K The first line
L The first data block
M The last line
N The last data block
every 2 plot every 2 line
every ::3 plot from the 3-rd lines
every ::3::5 plot from the 3-rd to 5-th lines
every ::0::0 plot the first line only
every 2::::6 plot the 1,3,5,7-th lines
every :2 plot every 2 data block
every :::5::8 plot from 5-th to 8-th data blocks

Теперь осталось построить два графика на одном:
plot "./RAWMEANmeasurementresult" using 4:($3-255.22579):7 title "Digital values of photosensor signal" with yerrorbars linestyle 1, f(x) title "linear fitting function" with line

То есть строим зависимость колонки 3 от 4 и используем колонку 7 как источник погрешности. При этом накладываем аппроксимационную линию с помощью директивы f(x) title "linear fitting function" with line

Собственно, вот итог моих фокусов:

Красиво и вполне себе презентабельно, хоть в Nature отправляй.
Читать далее

Ребрендеринг блога, Эпизод 2: Новая надежда



29 коммент.
Что, не ждали!? А вот оно как! Даже отчаянные консерваторы и поклонники тезиса "Не сломалось - не чини" иногда делают это... А если серьёзно, то на смену шаблона меня подтолкнул мой старинный товарищ SAV, который однажды на линукс-поинте деликатно мне намекнул на страшные тормоза с отрисовкой шаблона моего блога. Ну, думаю, раз такое дело, надо принимать меры. И я их принял, о чём далее.

Новый шаблон я несколько обточил перед тем, как сломать старый, но блог "Записки дебианщика" (вместе с самим дебианщиком :-)) немного покукожит и поплющит, так как большая часть виджетов слетела и их надо восстанавливать героическим самоотверженным трудом. А в этом нелёгком деле авторский коллектив призывает на помощь благодарных читателей, дабы оные кидали тухлые помидоры в места наибольших скоплений багов.

Обновлено: на удивление, всё прошло довольно быстро и с минимальными потерями. Виджеты я перетащил со старого шаблона, самые занудные виджеты реализованы уже в Блоггере (гугловцы не дремлют).

Новая идея такая: на главной - только один пост, и при том укороченный (с помощью fullpost). Все кнопки, виджеты и гаджеты снесены в подвал (вниз страницы) - это особенность нового одноколоночного шаблона. Так как здесь важен текст, а не навороченное оформление, я выбирал самый простой шаблон при внешней презентабельности и минимализме. Основной шрифт Trebuchet - как и прежде, и по крайней мере в Firefox масштабируется колесом мыши без косяков.
Обращаю внимание пользователей Microsoft Internet Explorer: в коде шаблона о вашем браузере написано много нехороших слов, так что если что-то отображается неправильно, то в этом виноваты не только кривые руки автора блога :-)
Так вот, пост на главной один, а остальное ищется локальным поиском (внизу слева), с помощью облака тегов или непосредственно по архиву блога (стандартный гугловский виджет). Функциональность вроде не пострадала. Предложения по улучшению принимаются (и пока у меня есть время их воплотить).

Немножко истории
Решил выложить предыдущие версии блога - как он выглядел раньше.
Сначала я решил не мудрствовать и просто выбрал стандартный шаблон Sand Dollar, но выглядит он вполне сносно:


Потом был шаблон с листьями, который я нашёл где-то на окраине Интернета и который я установил тогда, когда был Великий Переход Blogger со статических шаблонов на динамические (после этого отпала необходимость делать Republish your blog - ветераны помнят, что это). В шаблон с листьями я со временем напихал столько хаков и джаваскриптов, что со роптать начали даже самые стойкие орлы. Шаблон содержал постоянно регенерируемую градиентную заливку (без неё шаблон не смотрелся вообще) - выглядел красиво:


... но тормозить под нагрузкой джаваскриптов стал безбожно.
И вот, когда в очередной раз мне начали выносить мозг написанием научно-технического отчёта и переоформлением его в Microsoft Word (ну, вы поняли, да?), мне и пришла в голову шальная мысль - а не сменить ли мне шаблон. Полдня поисков, и вот, собственно, результат.

Тормозить здесь просто нечему (в шаблоне только одно внешнее изображение - в заголовке). Код довольно прост и компактен, а большая часть хаков стали не нужны, так как они уже реализованы командой Blogger.

Кстати, с убунтой бежево-коричневая расцветка шаблона не связана никоим образом: просто цветовая гамма спокойная и (как справедливо отмечают другие комментаторы) глаза не режет.
Читать далее

Маршруты и треки с помощью GPS-навигаторов Garmin



6 коммент.
Отслеживание перемещений по GPS (tracking) это довольно интересная и полезная возможность современных навигаторов. Например, вы пошли в поход или просто в парк, и долго блуждали, пока искали правильный путь - со включённым отслеживанием вы потом сможете дома посмотреть, как можно было бы срезать путь. Или, что тоже важно, по этим данным можно найти обратную дорогу.

Собственно, на навигаторе всё довольно просто: в зависимости от модели, трекинг включается одной-двумя кнопками (в Garmin GPSmap 60CSX - главное меню - Track - ON). После этого на экране должны оставаться точки, которые обозначают ваш путь по местности. Эти данные в абсолютных координатах хранятся в самом навигаторе, и скачать их оттуда можно в Linux довольно просто.

Скачиваем треки в гармине под Linux
Для этого нам понадобится консольная утилита gpsbabel. Её исходники нужно скачать с официального сайта (или посмотреть в репозиториях своего любимого дистрибутива) и собрать. Далее в нашем распоряжении появляется собственно gpsbabel, с помощью которого треки и скачиваем. Вот как это происходит (утянуто у тов. jetxee из этого поста):

Можно загрузить трек и точки маршрута с устройства при помощи программы gpsbabel, из командной строки. Если устройство подключено к /dev/ttyUSB0, а нужен трек с точками в формате GPX, то получить его можно так:
$ gpsbabel -t -w -i garmin -f /dev/ttyUSB0 -o gpx -F мойтрек.gpx
Другой способ получить эту информацию — скопировать с устройства GPX-файл в режиме USB Mass Storage, а потом уже его конверировать-преобразовывать… Этот файл с названием вида ГГГГММДД.gpx появляется на карточке памяти только если включена соответствующая функция в приборе.

Ну и зачем это всё надо!?
Ответ на этот вопрос я хочу дать в виде примера. Вот, например, был я не так давно в замечательном парке Покровское-Глебово. Парк этот замечателен в первую очередь тем, что его вовсе не так просто найти, как это может показаться на первый взгляд, а найдя - ориентироваться в нём. Для меня это превратилось в увлекательное путешествие и освежение в памяти навыков спортивного ориентирования на местности, чем я увлекался в горячую пионерскую юность...

Итак, по результатам моих хождений по мукампо парку, появился файл с расширением GPX, который я скачал с помощью gpsbabel (см. немного выше). И что с ним, спрашивается, делать? А вот что. Скачиваем замечательную программу JOSM, которая позволяет редактировать карты OpenStreetMap (OSM). Как легко догадаться, программа на Java, и просит эту саму джаву не древнее версии 1.5. Выглядит сама программа примерно так:


После этого можем скачать карту с OpenStreetMap и загрузить её в JOSM для просмотра. Интерфейс на Java, так что набираемся терпения и ждём, пока отрисуется. Далее можно открыть скачанный трек в формате GPX и он должен стать новым слоем (над картой). Тонкая серая извилистая линия, помеченная на скриншоте красными стрелками, это и есть мой путь по парку.
Собственно, из него я потом узнал, как пройти более коротким путём и что в парке мне не удалось с первого захода посмотреть. Довольно удобно так же использовать трекинг для редактирования OpenStreetMap, особенно если вы хорошо знаете район - с помощью треков можно вносить в карты улицы и дома. Но об этом как-нибудь в следующий раз...
Читать далее

Garmin 60CSx: технические особенности устройства и карты для Garmin



8 коммент.
В этом посте мне хотелось собрать раскиданные там и сям разные технические особенности GPS-навигатора Garmin 60CSx. Кроме того, несколько замечаний о картах для Garmin 60CSx. Собственно, о них далее.

Где скачать карты для Garmin? Собственно, на торрентах или пойти и честно воспользоваться картами OpenStreetMaps.
Уже готовые карты OSM по городам есть здесь. Или можно отправиться на сайт OpenStreetMaps, зарегистрироваться там и скачать карту нужной области честно и бесплатно.

Для этого заходим на http://www.openstreetmap.org/ и регистрируемся. Далее выделяем область карты, которую хотим экспортировать (для последующей закачки в навигатор), жмём на Экспорт и просим карту в OSM формате - через некоторое время получаем файлик map.osm. Теперь скачиваем mkmap отсюда, как завещал ув.тов. jetxee в своей бессмертной статье, оно на джаве и требует сановскую джаву версии старше 1.5. С её помощью компилируем в полученный OSM-файл в img формат. Получившийся файл заливаем в гармин с помощью sendmap.

Однако с картами OpenStreetMap есть одна проблема: не дают скачать сразу большую карту (я с жадности запросил у сервера векторную карту всей Москвы с областью). Если нужны большие карты, например, всей РФ, можно податься на Cloudmade.com и скачать оттуда. Этот сайт содержит уже скачанные карты местностей в формате OSM (которые мы потом перегоняем в img для Гармина) и собственно файл IMG, который можно закачать в навигатор.


Закачивание карт в Garmin 60CSx
По сообщениям разных осведомлённых орлов, во внутренней памяти (internal) может находиться до 3 карт, тогда как на флешке (microSD) - только одна. Хотя, как совершенно справедливо попенял многоуважаемый комментатор diaword, на самом деле, никто не мешает скачать несколько карт и потом собрать из них одну. Это можно сделать с помощью утилиты Mkgmap, а её ключик --gmapsupp позволяет собрать результирующую карту из нескольких отдельных и потом залить в навигатор. Файл gmapsupp.img является архивом из нескольких карт *.img, причем их можно как упаковывать, так и обратно распаковывать с помощью sendmap.

А такой финт, как закачка четырёх файлов карт сразу:
Gmapbmap.img -- базовая карта
Gmapsupp.img -- ваша карта
Gmapsup2.img -- другая карта
Gmapprom.img -- другая карта
на Garmin 60CSx не проходит, к сожалению.

Размер одной карты (img-файл) не может превышать 2Gb, хотя карта может состоять из кусков, число этих кусков не может быть больше 2025.

Комментарий насчёт экрана Garmin 60CSx
В Сети есть много критики по поводу низкого разрешения (160х240 пикселей) трансфлективного экрана у 60CSx. Критика понятна, так как есть другие навигаторы с более высоким разрешением. Но друзья, мы же помним, зачем гарминовцы эту модель выпускали? Правильно, для туристов, рыбоволовов, любителей активного отдыха и прочих экстремалов. Там важно не любоваться на карты, а быстро понять, где ты находишься.

Чтобы дать понять всю прелесть экрана 60CSx в походных условиях, вот фотография face-to-face: мой телефон Motorola 1200AE и 60CSx. На мобильнике подсветка включена на полную катушку, а на Гармине она не включена вообще.

И кто из них продержится дольше - думаю, понятно.


Память и подключение
Подключение происходит через miniUSB кабель как в режиме MassStorage, так и по специльному протоколу. И тот, и другой вариант поддерживаются в Linux.
В комплекте идёт карта microSD на 64Mb, максимальная поддерживаемая ёмкость карты 4GB micro SDHC.

Батареи

Удобнее использовать комплект аккумуляторов: от двух NiMH аккумуляторов ёмкости 2700mA*h устройство будет работать 16-20 часов.
Читать далее

QtOctave - графическая оболочка для Octave



13 коммент.
Хотя MATLAB и правит миром численных математических расчётов, в этом деле ему зреет очень хорошая альтернатива - GNU/Octave. И хотя у Октавы много проблем, таких как слабая документация и в основном консольный режим работы, есть и хорошие новости: проект QtOctave, ставящий своей целью сделать графическую среду разработки для Octave, весьма неплох. О нём и будет этот небольшой пост.

Установка
Для того, чтобы поставить QtOctave, вам потребуется скачать бинарник с сайта авторов и установить пакет octave в вашем дистрибутиве. Собранный и готовый бинарник прямо с сайта qtoctave_binaries_Linux_i386-0.8.1_svn166.binaries.tar.bz2 . Далее устанавливаем QtOctave по инструкции, то есть делаем sudo ./install.sh

В свежих версиях дистрибутивов QtOctave наличествует в репозиториях, и установить её можно просто и легко:
aptitude install qtoctave
По зависимостям потянется и новая версия GNU/Octave, если она ещё не установлена.


Работа
Собственно, открываем графическую консольку и пишем:
qtoctave
Перед вами развернётся графическая благодать, в которой замигает разноцветными огнями вся неимоверная мощь Octave. Разворачиваем одно из окон и открываем там свой скрипт на MATLAB\Octave. Выглядит это так:

По умолчанию можно просматривать переменные, список последних команд и файлов. В общем-то, для работы особенно больше ничего и не нужно. Развернув окно внутренней консоли в QtOctave, можно работать непосредственно с командной строкой Октавы и при этом видеть список активных переменных.


Сразу из замеченных недостатков: в графической консоли внутри QtOctave нельзя использовать подсказку по клавише TAB, при этом оно переходит в режим правки. Так же хотелось бы попенять на то, что QtOctave
не сохраняет расположение окон. Но это в общем не так бросается в глаза: при некотором навыке работы с Октавой или Матлабом работать вы будете не с консолью, а с редактором, как уже описывалось ранее.

Так же в комплекте идёт справка в формате HTML, причём весьма добротная. Конечно, до матлабовской ещё очень и очень далеко, но уже что-то. И главное, что это в комплекте, то есть batteries included.
То есть можно не только работать в Octave, но ещё и получать справку по командам, хотя и весьма базовую.


Заключение

В целом впечатление QtOctave производит очень благоприятное. Хотя Octave можно пользоваться таким же способом, как и MATLAB, о чём уже писалось, просмотр переменных и история команд в графическом виде это очень полезные возможности QtOctave. Хочется пожелать успехов проекту и дальнейшего развития.

Так же можно посмотреть в сторону
Python и SciPy. Как советуют товарищи питонисты, для этого есть следующие инструменты:
  • Python(x,y) готовый дистрибутив питона для научных нужд (batteries included).
  • SPYDER (графическая оболочка, входит также в Python(x,y) в дополнение к Eclipse)
Так же можно посмотреть в сторону IPython.

К сожалению, главный (и единственный!) разработчик QtOctave прекратил работу над проектом. Вот чем стоило бы заняться, КДЕшники, а не пилить свистульки типа фильтров Ланцоша и прочей мишуры...
Читать далее

Научная поисковая система на вашем Linux-десктопе



10 коммент.
Некоторое время назад я писал о SWISH++, и вот теперь мне хотелось бы обобщить написанное в более краткой форме. Проблема поиска нужной статьи, если не помнишь точно где она находится в каталогах, действительно серьёзная.


1. Поиск дубликатов
Итак, когда я накачал нужных мне статей из Интернета, я прежде всего смотрю, есть ли они у меня в коллекции с помощью fdupes. Эта программа ищет дубликаты файлов:
$ fdupes -rd .
Точка в конце говорит о том, что искать дубликаты fdupes будет, начиная с текущего каталога, поэтому можно в каталоге со статьями сделать подкаталог 1/ и набросать туда скачанные статьи.

Fdupes сравнивает файлы как побайтово, так и с помощью подсчёта md5-суммы, работает невероятно быстро, сортировка производится в полуавтоматическом режиме: программа выводит в консоли дублирующиеся файлы и спрашивает, какой из них оставить. Об этом уже говорилось в статье о подходах к сортировке PDF-файлов.


2. Индексация текста в PDF-файлах
Сначала из
документов pdf вытаскиваем текст, для чего просим утилиту find найти все файлы PDF и для каждого найденного выполнить pdftotext без выдачи предупреждений и без вставки символов разрыва страницы:
find -name '*.pdf' -exec pdftotext -nopgbrk -q {} \;
Надо отметить, что pdftotext хорошо работает только для английского языка, на котором, в общем, все статьи и написаны.

Теперь индексируем все текстовые файлы - в этом нам поможет собрат SWISH++ по имени index++ для индексации текстовых файлов:
index++ -e "text:*.txt" .
Точка в конце означает, что поиск ведётся с текущего каталога. Подробнее об индексации и автоматизации этого процесса сказано здесь.

В результате в текущем каталоге появится файл swish++.index где, собственно, лежит информация об индексировани файлов. Теперь всё готово для поиска.


3. Ищем в архиве статей нужное
Для поиска используем search++ которая найдёт по нашему запросу в индексированной базе swish++.index файлы. Вот пример поиска статьи по математической морфологии, в которых нет упоминания про медицину:
$ search++ morphology and erosion and dilation not medicine
Мгновение спустя вижу результат (вывод сокращён):
# results: 125
99 ./Krylov2.txt 3771 Krylov2.txt
49 ./13300407.txt 3103 13300407.txt
46 ./morph1.slides.printing.6.txt 4369 morph1.slides.printing.6.txt
37 ./lecture_morphology_sara.txt 6746 lecture_morphology_sara.txt
30 ./SIGGRAPH2002_Sketch-Mitchell.txt 5308 SIGGRAPH2002_Sketch-Mitchell.txt
26 ./MorphologicalImageProcessing.txt 7642 MorphologicalImageProcessing.txt
25 ./phdsymp2002_ledda.txt 8298 phdsymp2002_ledda.txt
23 ./lab2_manual.txt 9313 lab2_manual.txt
23 ./Project 1.txt 9946 Project 1.txt
22 ./morphology.txt 11212 morphology.txt
22 ./edg/morphology.txt 11212 morphology.txt
22 ./slides-6-geometry.txt 11717 slides-6-geometry.txt
22 ./V1BFOGG8.txt 10797 V1BFOGG8.txt
18 ./71650638.txt 13978 71650638.txt
Первая колонка - релевантность, вторая - расположение файла относительно текущей директории, третья - размер файла, четвёртая - имя. Просто и понятно.

Теперь в консольке набираю kdpf
./Krylov2.pdf и смотрю нужную мне статью. И всё.

Ссылки
Собственно, документации о SWISH++ очень мало, так что в основном я решил собрать свои предыдущие записи в один пост:
- поиск и удаление дубликатов файлов с помощью fdupes;
- выделение текста из PDF-файлов и их индексация;
- поиск в индексированных файлах с помощью SWISH++
Читать далее

Чтение MAT-файлов MATLAB в nip2



3 коммент.
То, о чём так долго говорили красные, белые, зелёные, и даже голубые - свершилось. Теперь замечательный графический анализатор nip2 полностью поддерживает чтение MAT-файлов, в которых MATLAB записывает данные рабочего окружения с двойной точностью (double precision). И хотя в основной ветке этой возможности ещё нет, в SVN-репозитории оно уже появилось благодаря скромным усилиям автора этих строк и John Cupitt - одного из авторов nip2 и библиотеки VIPS.

На всякий случай: nip2 это графический анализатор изображений (это не привычный gimp или photoshop), который создавался специально для работы с огромными файлами и научных применений. Но он может быть полезен и простым пользователям: с его помощью легко открывать, просматривать, кадрировать огромные файлы. Или, например, склеить две фотографии в одну - как склеивают панорамы.


Для чего нужно открывать MAT-файлы в nip2
Упреждая возможные вопросы "а зачем нам проприетарный mat когда есть csv" отвечу: запись в открытый формат CSV в матлабе происходит несколько нетривиальным образом и можно записать только одну переменную. Более того, если забыть указать несколько важных параметров, можно сильно потерять в точности сохраняемых данных. И главное, что уже много результатов научных экспериментов сохранено в MAT-формате.

Периодически возникает необходимость быстро просмотреть эти данные (это изображения) в каком-нибудь просмотрщике без необходимости загружать MATLAB. Таковых просмотрщиков я не знаю - открыть MAT-файл может только GNU/Octave с помощью библиотеки matio. Так что эта возможность очень нужна и востребована.

Установка nip2 и VIPS

Хотя об установке nip2 я уже писал, тем не менее, повторюсь. Сначала нужно скачать отсюда из support-зоны самый свежак. Сначала собираем VIPS и устанавливаем пакет, потом собираем nip2 и тоже устанавливаем. Последние версии (vips7.18.XX) со старыми версиями Питона могут не собраться, так что для этого при сборке пользуем ключ --without-python и собираем.

Для себя и своих студентов я собрал пакеты под Debian Etch и архитектуру i386 (да-да, я в конкретном бронепоезде):
После этого добавляем программу в меню вашего оконного менеджера или запускаем прямо из графической консоли командой nip2.


Просмотр MAT-файлов MATLAB в nip2

Здесь всё довольно просто: в диалоге открытия явно указываем, что хотим просмотреть MATLAB's mat-files и далее открываем такой файл. Пример на скриншоте - легендарная Лена
(а кто такая Лена?)


А теперь примерчик посложнее - загружаем изображение усреднённых темновых шумов цифровой камеры и берём от них Фурье-преобразование (на том же скриншоте открыта в левом нижнем углу неудачная фотография от скоростной съёмки):


Так что наши данные теперь можно просмотреть без томительного ожидания, пока MATLAB откроет эти файлы. Кстати о данных в форматах CSV и MAT...


Данные в CSV и MAT-форматах: особенности записи MATLAB и просмотр nip2
Эту заметку я хотел сделать отдельным постом, но решил выложить здесь же. Появился тут вопрос: как сохраняет MATLAB данные с плавающей точкой в разных форматах. Для этого мы провели маленькое расследование...


Подготовка
Ответ состоит из нескольких частей. Да, Матлаб может сохранять данные в своём формате mat, и его может прочесть та же Octave (теперь и nip2 с использованием библиотеки matio). Для проверки сгенерируем матрицу

>> a = magic(5)

a =

17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

>> b =a./3

b =

5.6667 8.0000 0.3333 2.6667 5.0000
7.6667 1.6667 2.3333 4.6667 5.3333
1.3333 2.0000 4.3333 6.6667 7.3333
3.3333 4.0000 6.3333 7.0000 1.0000
3.6667 6.0000 8.3333 0.6667 3.0000

>> b(2,2)=1.09878432753084573248523475
>> b(2,3)=2^20

Видим только первые четыре числа после запятой - это потому, что по умолчанию MATLAB отображает числа в коротком формате. Изменить этот формат можно командой format type.

Чтобы сделать задачу более наглядной, в матрицу записали два числа: одно с разными числами после запятой, а второе - очень большое (2^20). Теперь сохраняем в MAT-файл и CSV командами:
save('magic5x5doubleafterformatlong.mat', 'b'); %% это сохраняется MAT-файл
csvwrite('magic5x5double-afterformatlong.csv',b); %% это сохраняется CSV-файл

Теперь открываем их и сравниваем с исходниками...

Данные в MAT-файле.
В MAT-файлах всё чисто: он сохраняет так же, как и открывает.
>> load('magic5x5doubleafterformatlong.mat')
>> b
b =
1.0e+06 *
Columns 1 through 4
0.00000566666667 0.00000800000000 0.00000033333333 0.00000266666667
0.00000766666667 0.00000109878433 1.04857600000000 0.00000466666667
0.00000133333333 0.00000200000000 0.00000433333333 0.00000666666667
0.00000333333333 0.00000400000000 0.00000633333333 0.00000700000000
0.00000366666667 0.00000600000000 0.00000833333333 0.00000066666667
Column 5
0.00000500000000
0.00000533333333
0.00000733333333
0.00000100000000
0.00000300000000
>> b(2,2)
ans =
1.09878432753085
>> b(2,3)
ans =
1048576

Данные в CSV-файле.
А вот тут начинаются приключения. MATLAB записывает в CSV формат данные с точностью, такой же, как при отображении. То есть, например, при отображении используется вывод только первых 4 чисел после запятой - следовательно, сохранены они в CSV будут так же.

>> b(2,2)

ans =

1.0988

С большими числами тоже самое: они сохраняются в экспоненциальной форме с точностью, установленной для отображения (по умолчанию 4 знака). Это так же видно в CSV-файле (записывает с той точностью, с которой отображает). У одной и той же матрицы, сохранённой в CSV и MAT сходный размер.


>> b(2,3)=2^20

b =

1.0e+06 *

0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 1.0486 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000
0.0000 0.0000 0.0000 0.0000 0.0000

>> b(2,3)

ans =

1048600

>> 2^20

ans =

1048576

Именно так оно и происходит по умолчанию: MATLAB просто округляет числа при записи в CSV до четырёх значащих чисел. Для того, чтобы запись происходила с нужной нам точностью в CSV, следует использовать команду dlmwrite и явно указывать точность. Например так:

>> dlmwrite('magic5x5double1-dlmwrite-precision12f.csv', b, 'precision', '%12.12f')

Это записывает матрицу в CSV формат с переменной b и обеспечивает точность 12 значащих чисел. Так что стоит аккуратнее обходиться с командами записи: csvwrite вам запишет, конечно, переменную, но с малой точностью. Это может стать источником трудноуловимых проблем.


Отображение данных в MAT и CSV форматах в nip2
Теперь, возвращаясь к теме поста, в последних версиях (nip2 и vips > 7.18.2) замечательного графического анализатора nip2 можно просматривать не только данные в CSV, но и в MAT-файлах. Это очень и очень удобная возможность: например, усреднённое изображение в MAT-файле можно проанализировать и посмотреть без необходимости загружать лишний раз MATLAB. Особенно это актуально, если изображение в MAT-файле больших размеров. Точность просмотра CSV и MAT-данных составляет 5 значащих цифр.
Читать далее