В качестве примера возьмем простой скрипт, с помощью которого можно создать следующее изображение:
Будем считать, что нашей целью является создание изображения в формате eps или pdf с целью дальнейшей вставки его в статью для публикации. Сам скрипт выглядит следующим образом:
void createHisto( void ) { TCanvas * c1 = new TCanvas(); TH1 * histo = new TH1F( "h1", "DCS vs. Energy", 10, 400., 600. ); Double_t content[] = { 0.0, 0.115, 0.145, 0.158, 0.170, 0.182, 0.180, 0.172, 0.154, 0.140, 0.132, 0.0 }; Double_t errors[] = { 0.0, 0.0015, 0.0012, 0.0008, 0.0016, 0.0023, 0.0018, 0.0013, 0.0014, 0.0006, 0.0002, 0.0 }; histo->SetContent( content ); histo->SetError( errors ); histo->GetXaxis()->SetTitle( "E_{cm}, MeV" ); histo->GetYaxis()->SetTitle( "d#sigma/d#Omega, mb/sr" ); histo->SetStats( kFALSE ); // do not draw stats box histo->Draw(); c1->SaveAs( "c1.eps" ); } void histoTest( void ) { gROOT->SetStyle( "Plain" ); gStyle->SetTitleBorderSize( 0 ); // do not draw frames around title gStyle->SetTitleOffset( 1.2, "xy" );// do not let axes' titles overlap ticks createHisto(); if ( gROOT->IsBatch() ) exit( 0 ); }Обратите внимание, что в подписях к осям гистограммы используется вариант Latex для ROOT, стиль gStyle установлен в Plain, а рамка вокруг титула удалена. Отсутствие рамки вокруг титула упрощает решение задачи в первом и третьем подходах (см. ниже).
Для сохранения картинки наверху в файле c1.eps нужно создать скрипт histoTest.C с указанным содержимым и запустить root в пакетном режиме:
root -b histoTest.CПусть нашей задачей будет замена титула изображения на ДСР в зависимости от энергии и меток mb/sr, MeV и cm на мб/ср, МэВ и цм соответственно.
Наивная подстановка русских надписей в скрипт histoTest.C приведет к выводу в изображение c1.eps "кракозябр". Что же не так с ROOT? Нативный графический бэкенд ROOT не поддерживает кириллицу. Точка. Для решения проблемы ниже представлены три подхода, которые приводятся в порядке улучшения качества решения и полноты, хотя ни один из них не является идеальным. Идеи второго и третьего подходов взяты из обсуждений здесь и здесь.
- Наиболее простое решение - сохранить исходное изображение в векторном формате svg и отредактировать его в каком-нибудь векторном редакторе, например в inkscape. Минусы здесь очевидны. Редактировать придется вручную. Кроме изменения текста придется изменять обрамляющие его элементы, например компоненты рамки вокруг титула (которую мы предусмотрительно убрали в исходном скрипте).
- Использование Qt бэкенда (Qt layer) . Это был бы идеальный вариант, если бы не невообразимая глючность данного бэкенда. Из основных глюков стоит упомянуть: полупрозрачный или полностью прозрачный фон и шрифт абсолютно всех меню, невозможность использовать диалог сохранения файлов (!), невозможность сохранить валидное изображение в форматах eps и pdf (!). В данном подходе пришлось сохранять изображение как Save -> c1.png. Для использования Qt бэкенда нужно записать в файл ~/.rootrc следующие строки:
Gui.Backend: $(ROOTGUI) Gui.Factory: $(ROOTGUI) Gui.DefaultFont: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-5 Gui.MenuFont: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-5 Gui.MenuHiFont: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-5 Gui.DocFixedFont: -*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-5 Gui.DocPropFont: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-5 Gui.IconFont: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-5 Gui.StatusFont: -*-helvetica-medium-r-*-*-10-*-*-*-*-*-iso8859-5
Использование переменной среды ROOTGUI позволяет сохранить нативный бэкенд по умолчанию (однако придется добавить строку
export ROOTGUI=native
в ~/.bash_profile). Для того, чтобы запустить root с Qt бэкендом нужно ввести
ROOTGUI=qt root histoTest_qt.C
Скрипт histoTest_qt.C выглядит так:
void createHisto( void ) { //TCanvas * c1 = new TCanvas(); TH1 * histo = new TH1F( "h1", "´ÁÀ Ò ×ÐÒØáØÜÞáâØ Þâ íÝÕàÓØØ", 10, 400., 600. ); Double_t content[] = { 0.0, 0.115, 0.145, 0.158, 0.170, 0.182, 0.180, 0.172, 0.154, 0.140, 0.132, 0.0 }; Double_t errors[] = { 0.0, 0.0015, 0.0012, 0.0008, 0.0016, 0.0023, 0.0018, 0.0013, 0.0014, 0.0006, 0.0002, 0.0 }; histo->SetContent( content ); histo->SetError( errors ); histo->GetXaxis()->SetTitle( "E_{æÜ}, ¼í²" ); histo->GetYaxis()->SetTitle( "d#sigma/d#Omega, ÜÑ/áà" ); histo->SetStats( kFALSE ); // do not draw stats box histo->Draw(); //c1->SaveAs( "c1_qt.eps" ); } void histoTest_qt( void ) { gROOT->SetStyle( "Plain" ); gStyle->SetTitleBorderSize( 0 ); // do not draw frames around title gStyle->SetTitleOffset( 1.1, "xy" );// do not let axes' titles overlap ticks createHisto(); if ( gROOT->IsBatch() ) exit( 0 ); }
Заметили "кракозябры" внутри скрипта? Это еще одно неудобство. Скрипт выведен в общепринятой на сегодня кодировке UTF-8, а был записан в кодировке ISO-8859-5. В vim сохранение файла в данной кодировке обеспечивается командой
:set fenc=iso-8859-5
Однако при повторной загрузке этого файла в vim появятся всё те же "кракозябры" и новые русские записи не удастся добавить без полного переписывания русских символов заново. Возможно существуют редакторы, в которых проблема перевода в разные кодировки решается проще.
Еще один интересный момент. Создание канваса c1 в данном варианте закомментировано. Если оставить его незакомментированным, то диапазон оси ординат изменится, и на месте гистограммы окажется чистое белое поле (!). Это еще раз подтверждает тот факт, что с текущей реализацией Qt бэкенда нужно быть очень осторожным.
Изображение, полученное с помощью Qt бэкенда, выглядит так:
Заметьте также, что Qt бэкенд применил преобразования локали: вместо точек в вещественных числах на координатных осях стоят запятые. - Третий подход основан на Latex и двух латеховских модулях - standalone и psfrag. Оба модуля можно найти на ctan.org. В пакет texlive для Fedora 14 они не входят, однако существует отдельный репозиторий texlive, в котором эти модули присутствуют. Информация об этом репозитории здесь. Преимущество данного подхода в том, что он полностью автоматизирован. Скрипт histoTest_latex.C выглядит так:
void createHisto( void ) { TCanvas * c1 = new TCanvas(); TH1 * histo = new TH1F( "h1", "CT", 10, 400., 600. ); Double_t content[] = { 0.0, 0.115, 0.145, 0.158, 0.170, 0.182, 0.180, 0.172, 0.154, 0.140, 0.132, 0.0 }; Double_t errors[] = { 0.0, 0.0015, 0.0012, 0.0008, 0.0016, 0.0023, 0.0018, 0.0013, 0.0014, 0.0006, 0.0002, 0.0 }; histo->SetContent( content ); histo->SetError( errors ); histo->GetXaxis()->SetTitle( "CX" ); histo->GetYaxis()->SetTitle( "CY" ); histo->SetStats( kFALSE ); // do not draw stats box histo->Draw(); c1->SaveAs( "c1_latex.eps" ); } void histoTest_latex( void ) { gROOT->SetStyle( "Plain" ); gStyle->SetTitleBorderSize( 0 ); // do not draw frames around title gStyle->SetTitleOffset( 1.2, "xy" );// do not let axes' titles overlap ticks createHisto(); if ( gROOT->IsBatch() ) exit( 0 ); }
Главным отличием от исходного скрипта является то, что оригинальные титул и подписи к осям заменены метками CT, CX и CY, которые будут обрабатываться в теховском скрипте с помощью psfrag. Идея psfrag весьма проста - заменить метки в исходном ps или eps файле указанными значениями. Отмечу сразу, что метки для подстановки следует выбирать короткие, иначе psfrag может сгенерировать ломаный файл dvi. Скрипт c1_latex.tex выглядит так:
\documentclass{standalone} \usepackage[T2A]{fontenc} \usepackage[utf8x]{inputenc} \usepackage[dvips]{graphicx,color} \usepackage{psfrag} \begin{document} \psfrag{CT}[lt][lt][1.8]{\bf ДСР в зависимости от энергии} \psfrag{CX}[rt][rt][1.4]{\bf $\mathbf{E_{\mbox{цм}}}$, МэВ} \psfrag{CY}[rt][rt][1.4]{\bf $\mathbf{d\sigma/d\Omega}$, мб/ср} \includegraphics{c1_latex.eps} \end{document}
О параметрах psfrag можно прочитать в документации к данному пакету; кратко, первый параметр в фигурных скобках является заменяемой меткой, последний параметр в фигурных скобках - подстановкой, первые два параметра в квадратных скобках после метки - позиционными якорями, третий параметр в квадратных скобках - коэффициентом масштабирования шрифта. Пакет standalone позволяет сохранить исходные размеры изображения.
Русификация надписей может быть произведена с помощью отдельного шелл-скрипта mkrus:
#!/bin/sh # source root macro root -b histoTest_latex.C # run psfrag latex c1_latex # make pdf dvips c1_latex ps2pdf c1_latex.ps # delete temporary files rm c1_latex.eps c1_latex.ps c1_latex.dvi c1_latex.aux c1_latex.log # make eps pdftops -eps c1_latex.pdf
Этот скрипт создает два изображения: c1_latex.eps и c1_latex.pdf, которые выглядят так:
В данном изображении используется шрифт Serif - просто в моем дистрибутиве texlive не нашлось русского Sans Serif шрифта c кодировкой T2A (которая используется в c1_latex.tex). Если необходим шрифт Sans Serif, нужно установить его из внешних источников.
Комментариев нет:
Отправить комментарий