Add global settings & simple WCS given by user

This commit is contained in:
eddyem 2016-08-03 18:28:17 +03:00
parent a910538d33
commit 21b870159d
13 changed files with 675 additions and 169 deletions

View File

@ -14,7 +14,7 @@ message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
if(NOT DEFINED LOCALEDIR)
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
endif()
set(SOURCES takepic.c usage.c camtools.c am.c macros.c)
set(SOURCES defhdrs.c takepic.c usage.c camtools.c am.c macros.c)
if(NOT DEFINED NOBTA)
set(SOURCES ${SOURCES} bta_print.c)
add_definitions(-DUSE_BTA)
@ -28,6 +28,9 @@ endif()
if(DEFINED TELLAT)
add_definitions(-DTELLAT=${TELLAT})
endif()
if(DEFINED TELFOCUS)
add_definitions(-DTELFOCUS=${TELFOCUS})
endif()
if(NOT DEFINED PROCESSOR_COUNT)
set(PROCESSOR_COUNT 2) # by default 2 cores
set(cpuinfo_file "/proc/cpuinfo")

12
README
View File

@ -3,7 +3,7 @@ This utilite depends on library libapogee & C-wrapper over it
First, you should install a latest version of libapogee from directory "libapogee"
or from original site: http://www.randomfactory.com/downloads/
If you will meet a bug in link stage ("can't find -lboost_regex-mt") cd to directory
libapogee-[version]/apogee and run
libapogee-[version]/apogee and run
$ sed -i 's/boost_regex-mt/boost_regex/g' Makefile
after this small fix cd .. and run make again.
@ -34,4 +34,14 @@ By default observatory location is SAO RAS, to change coordinates define:
* -DTELLAT=lattitude in degr
* -DTELLONG=longitude in degr
* -DTELALT=altitude in m
* -DTELFOCUS=focal ratio of telescope in metres
user can store default headers in ~/apogee_hdrs.fits
user can give additional keys as command line parameters
to calculate simplest CDx_x coefficients user can give parameter ROT0:
- for left-handed system it shoud be less than 0 (-360..0)
CROTA2 = -ROT0 + PARANGLE - VAL_P
- for right-handed > 0 (0..360)
CROTA2 = ROT0 - PARANGLE + VAL_P

51
TODO Normal file
View File

@ -0,0 +1,51 @@
Правильно писать шапку:
DATA - дата записи файла формата dd/mm/yy (UTC)
DATE-OBS - дата считывания данных с матрицы (начало, середина или конец - указывать в комментарии), dd/mm/yy, UTC
ORIGIN - место записи (SAO RAS, правильно)
INSTRUME - название прибора
CREATOR - название ПО, записавшего файл
EQUINOX - эпоха системы координат, используемой в файле (правильно)
EPOCH - Deprecated
Комментарии, помимо COMMENT, могут просто начинаться с 9 столбца, оставляя первые 8 пустыми
Аналогично для HISTORY
(во всех трех случаях в столбце 9 не должно быть =)
Если данные непонятно в чем (особенно это касается таблиц), нужно использовать ключи:
BUNIT - binary unit (как для изображения, так и для таблиц)
TUNITn - единицы n-го столбца таблицы
см. http://www.lsw.uni-heidelberg.de/iau/units.html
BITPIX:
8 - uint8_t
16 - int16_t (BZERO=32768 для uint16_t)
32 - int32_t (BZERO=2147483648 для uint32_t)
-32 - float
-64 - double
EXTEND = T
этот параметр не обязательно означает наличие "расширений", но если его нет, это гарантирует
отсутствие расширений
Все расширения (изображения, таблицы и т.п.) должны начинаться со слова
XTENSION = [тип] - тип расширения (например, XTENSION= 'TABLE'
далее обязательны BITPIX, NAXIS и NAXIS1, NAXIS2 ...
Если данные отсутствуют, пишем NAXIS1 = 0
Расширению можно дать имя (скажем, таблице):
EXTNAME = 'название'
их можно версионировать (EXTVER) и разделять по иерархии (EXTLEVEL)
ТАБЛИЦЫ: XTENSION='TABLE'
BITPIX=8 (ASCII)
NAXIS=2 (двумерная таблица)
NAXIS1= количество символов в строке таблицы (все столбцы)
NAXIS2= количество строк
PCOUNT=0 (ASCII)
GCOUNT=1
TFIELDS= количество столбцов

View File

@ -33,6 +33,8 @@
#include "camtools.h"
#include "bta_print.h"
#include "macros.h"
#include "usage.h" // command line parameters
#include "defhdrs.h"
#include <slamac.h> // SLA macros
extern void sla_amp(double*, double*, double*, double*, double*, double*);
@ -51,7 +53,7 @@ void calc_mean(double appRA, double appDecl, double *r, double *d){
double ra, dec;
appRA *= DS2R;
appDecl *= DAS2R;
DBG("appRa: %g, appDecl: %g", appRA, appDecl);
//DBG("appRa: %g, appDecl: %g", appRA, appDecl);
double mjd = JDate - jd0;
slaamp(appRA, appDecl, mjd, 2000.0, &ra, &dec);
ra *= DR2S;
@ -60,10 +62,9 @@ void calc_mean(double appRA, double appDecl, double *r, double *d){
if(d) *d = dec;
}
#define CMNTSZ 79
char comment[CMNTSZ + 1];
#define CMNT(...) snprintf(comment, CMNTSZ, __VA_ARGS__)
#define FTKEY(...) WRITEKEY(fp, __VA_ARGS__, comment)
char comment[FLEN_CARD];
#define CMNT(...) snprintf(comment, FLEN_CARD, __VA_ARGS__)
#define FTKEY(...) WRITEKEY(__VA_ARGS__, comment)
#define WRITEHIST(fp) \
do{ if(test_headers){printf("HISTORY: %s\n", comment);}else{ \
int status = 0; \
@ -140,6 +141,7 @@ BTA_Queue *bta_queue = NULL;
void write_bta_data(fitsfile *fp){
char *val;
double dtmp;
//char buf[FLEN_CARD];
time_t t_now = time(NULL);
struct tm *tm_ut, *tm_loc;
tm_ut = gmtime(&t_now);
@ -215,29 +217,33 @@ void write_bta_data(fitsfile *fp){
double a2000, d2000;
calc_mean(InpAlpha, InpDelta, &a2000, &d2000);
CMNT("R.A. given by user (for J2000): %s", time_asc(a2000));
FTKEY(TDOUBLE, "INPRA0", &a2000);
dtmp = a2000 / 3600.;
FTKEY(TDOUBLE, "INPRA0", &dtmp);
CMNT("Decl. given by user (for J2000): %s", angle_asc(d2000));
FTKEY(TDOUBLE, "INPDEC0", &d2000);
dtmp = d2000 / 3600;
FTKEY(TDOUBLE, "INPDEC0", &dtmp);
calc_mean(CurAlpha, CurDelta, &a2000, &d2000);
CMNT("Current R.A. (for J2000): %s", time_asc(a2000));
FTKEY(TDOUBLE, "CURRA0", &a2000);
dtmp = a2000 / 3600.;
FTKEY(TDOUBLE, "CURRA0", &dtmp);
CMNT("Current Decl. (for J2000): %s", angle_asc(d2000));
FTKEY(TDOUBLE, "CURDEC0", &d2000);
dtmp = d2000 / 3600;
FTKEY(TDOUBLE, "CURDEC0", &dtmp);
// A / Azimuth
CMNT("Current object Azimuth: %s", angle_asc(tag_A));
dtmp = tag_A / 3600.; FTKEY(TDOUBLE, "A", &dtmp);
// Z / Zenith distance
CMNT("Current object Zenith: %s", angle_asc(tag_Z));
dtmp = tag_Z / 3600.; FTKEY(TDOUBLE, "Z", &dtmp);
// ROTANGLE / Field rotation angle
CMNT("Field rotation angle: %s", angle_asc(tag_P));
dtmp = tag_P / 3600.;FTKEY(TDOUBLE, "ROTANGLE", &dtmp);
// PARANGLE / Parallactic angle
CMNT("Parallactic angle: %s", angle_asc(tag_P));
dtmp = tag_P / 3600.;FTKEY(TDOUBLE, "PARANGLE", &dtmp);
CMNT("Telescope A: %s", angle_asc(val_A));
dtmp = val_A / 3600.; FTKEY(TDOUBLE, "VAL_A", &dtmp);
CMNT("Telescope Z: %s", angle_asc(val_Z));
dtmp = val_Z / 3600.; FTKEY(TDOUBLE, "VAL_Z", &dtmp);
CMNT("Current P: %s", angle_asc(val_P));
CMNT("Current P2 value: %s", angle_asc(val_P));
dtmp = val_P / 3600.; FTKEY(TDOUBLE, "VAL_P", &dtmp);
CMNT("Dome A: %s", angle_asc(val_D));

View File

@ -23,6 +23,7 @@
#include "camtools.h"
#include "usage.h"
#include "macros.h"
#include "defhdrs.h"
#ifdef USE_BTA
#include "bta_print.h"
@ -31,60 +32,6 @@
unsigned short max=0, min=65535; // extremums of current image
double avr, std; // average value and standard deviation
/*
* Fake util to show FITS keys in stdout
* when test_headers == 1
*/
void print_fits_header(fitsfile *fptr __attribute((unused)), int datatype,
char *keyname, void *value, char *comment){
void _ub(char* r, void* p){snprintf(r, 80, "%hhu", *(unsigned char*)p);}
void _b(char* r, void* p){snprintf(r, 80, "%hhd", *(char*)p);}
void _us(char* r, void* p){snprintf(r, 80, "%hu", *(unsigned short*)p);}
void _ui(char* r, void* p){snprintf(r, 80, "%u", *(unsigned int*)p);}
void _ul(char* r, void* p){snprintf(r, 80, "%lu", *(unsigned long*)p);}
void _s(char* r, void* p){snprintf(r, 80, "%hd", *(short*)p);}
void _i(char* r, void* p){snprintf(r, 80, "%d", *(int*)p);}
void _l(char* r, void* p){snprintf(r, 80, "%ld", *(long*)p);}
void _ll(char* r, void* p){snprintf(r, 80, "%lld", *(long long*)p);}
void _f(char* r, void* p){snprintf(r, 80, "%g", *(float*)p);}
void _d(char* r, void* p){snprintf(r, 80, "%g", *(double*)p);}
void _fc(char* r, void* p){snprintf(r, 80, "(%.8g, %.8g)",
((float*)p)[0], ((float*)p)[1]);}
void _dc(char* r, void* p){snprintf(r, 80, "(%.8g, %.8g)",
((double*)p)[0], ((double*)p)[1]);}
void _log(char* r, void* p){snprintf(r, 80, "'%s'", (int*)p ? "true" : "false");}
void _str(char* r, void* p){snprintf(r, 80, "'%s'", (char*)p);}
void _unk(char* r, void* p __attribute((unused))){sprintf(r, "unknown datatype");}
char tmp[81], res[81];
void (*__)(char*, void*);
switch(datatype){
case TBIT:
case TBYTE: __ = _ub; break;
case TSBYTE: __ = _b; break;
case TUSHORT: __ = _us; break;
case TUINT: __ = _ui; break;
case TULONG: __ = _ul; break;
case TSHORT: __ = _s; break;
case TINT: __ = _i; break;
case TLONG: __ = _l; break;
case TLONGLONG: __ = _ll; break;
case TFLOAT: __ = _f; break;
case TDOUBLE: __ = _d; break;
case TCOMPLEX: __ = _fc; break;
case TDBLCOMPLEX: __ = _dc; break;
case TLOGICAL: __ = _log; break;
case TSTRING: __ = _str; break;
default: __ = _unk;
}
__(res, value);
if(strlen(res) < 20)
snprintf(tmp, 80, "%-8s = %-20s", keyname, res);
else
snprintf(tmp, 80, "%-8s = %s", keyname, res);
snprintf(res, 80, "%s / %s", tmp, comment);
printf("%s\n", res);
}
/*
* set fun speed
* if user set option fan-speed=F, then speed would be set to F
@ -225,63 +172,60 @@ int writefits(char *filename, int width, int height, void *data){
TRYFITS(fits_create_file, &fp, filename);
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
// FILE / Input file original name
WRITEKEY(fp, TSTRING, "FILE", filename, "Input file original name");
WRITEKEY(TSTRING, "FILE", filename, "Input file original name");
/*
* Detector parameters
*/
// DETECTOR / detector
if(camera){
WRITEKEY(fp, TSTRING, "DETECTOR", camera, "Detector model");
WRITEKEY(TSTRING, "DETECTOR", camera, "Detector model");
}
// SENSOR / sensor
if(sensor){
WRITEKEY(fp, TSTRING, "SENSOR", sensor, "Camera sensor model");
WRITEKEY(TSTRING, "SENSOR", sensor, "Camera sensor model");
}
// INSTRUME / Instrument
if(instrument){
WRITEKEY(fp, TSTRING, "INSTRUME", instrument, "Instrument");
WRITEKEY(TSTRING, "INSTRUME", instrument, "Instrument");
}else
WRITEKEY(fp, TSTRING, "INSTRUME", "direct imaging", "Instrument");
WRITEKEY(TSTRING, "INSTRUME", "direct imaging", "Instrument");
snprintf(buf, 79, "%.g x %.g", pixX, pixY);
// PXSIZE / pixel size
WRITEKEY(fp, TSTRING, "PXSIZE", buf, "Pixel size in mkm");
WRITEKEY(TSTRING, "PXSIZE", buf, "Pixel size in mkm");
// XPIXELSZ, YPIXELSZ -- the same
WRITEKEY(fp, TDOUBLE, "XPIXELSZ", &pixX, "X pixel size in mkm");
WRITEKEY(fp, TDOUBLE, "YPIXELSZ", &pixY, "Y pixel size in mkm");
WRITEKEY(fp, TSTRING, "VIEW_FIELD", viewfield, "Camera field of view");
// CRVAL1, CRVAL2 / Offset in X, Y
if(X0) WRITEKEY(fp, TINT, "CRVAL1", &X0, "Offset in X");
if(Y0) WRITEKEY(fp, TINT, "CRVAL2", &Y0, "Offset in Y");
WRITEKEY(TDOUBLE, "XPIXELSZ", &pixX, "X pixel size in mkm");
WRITEKEY(TDOUBLE, "YPIXELSZ", &pixY, "Y pixel size in mkm");
WRITEKEY(TSTRING, "VIEWFLD", viewfield, "Camera field of view");
if(exptime == 0) sprintf(buf, "bias");
else if(shutter == 0) sprintf(buf, "dark");
else if(objtype) strncpy(buf, objtype, 79);
else sprintf(buf, "object");
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
WRITEKEY(fp, TSTRING, "IMAGETYP", buf, "Image type");
WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type");
// DATAMAX, DATAMIN / Max,min pixel value
ustmp = ((twelveBit) ? 4095 : 65535);
WRITEKEY(fp, TUSHORT, "DATAMAX", &ustmp, "Max pixel value");
WRITEKEY(TUSHORT, "DATAMAX", &ustmp, "Max pixel value");
ustmp = 0;
WRITEKEY(fp, TUSHORT, "DATAMIN", &ustmp, "Min pixel value");
WRITEKEY(TUSHORT, "DATAMIN", &ustmp, "Min pixel value");
// Some Statistics
WRITEKEY(fp, TUSHORT, "STATMAX", &max, "Max data value");
WRITEKEY(fp, TUSHORT, "STATMIN", &min, "Min data value");
WRITEKEY(fp, TDOUBLE, "STATAVR", &avr, "Average data value");
WRITEKEY(fp, TDOUBLE, "STATSTD", &std, "Standart deviation of data value");
WRITEKEY(TUSHORT, "STATMAX", &max, "Max data value");
WRITEKEY(TUSHORT, "STATMIN", &min, "Min data value");
WRITEKEY(TDOUBLE, "STATAVR", &avr, "Average data value");
WRITEKEY(TDOUBLE, "STATSTD", &std, "Standart deviation of data value");
// Temperatures
WRITEKEY(fp, TDOUBLE, "TEMP0", &temperature, "Camera temperature at exp. start (degr C)");
WRITEKEY(fp, TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
WRITEKEY(TDOUBLE, "TEMP0", &temperature, "Camera temperature at exp. start (degr C)");
WRITEKEY(TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
if(t_ext > -30.) // there's a hot temp sensor
WRITEKEY(fp, TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
WRITEKEY(TDOUBLE, "TEMPBODY", &t_ext, "Camera body temperature at exp. end (degr C)");
tmp = (temperature + t_int) / 2. + 273.15;
// CAMTEMP / Camera temperature (K)
WRITEKEY(fp, TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
WRITEKEY(TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
tmp = (double)exptime / 1000.;
// EXPTIME / actual exposition time (sec)
WRITEKEY(fp, TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)");
WRITEKEY(TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)");
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
WRITEKEY(fp, TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
WRITEKEY(TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
tm_starttime = localtime(&expStartsAt);
/*
* startTime = (long)expStartsAt;
@ -290,7 +234,7 @@ int writefits(char *filename, int width, int height, void *data){
*/
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", tm_starttime);
// DATE-OBS / DATE OF OBS.
WRITEKEY(fp, TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY-MM-DDThh:mm:ss, local)");
WRITEKEY(TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY-MM-DDThh:mm:ss, local)");
/*
* // START / Measurement start time (local) (hh:mm:ss)
* strftime(buf, 79, "%H:%M:%S", tm_starttime);
@ -298,30 +242,32 @@ int writefits(char *filename, int width, int height, void *data){
*/
// OBJECT / Object name
if(objname){
WRITEKEY(fp, TSTRING, "OBJECT", objname, "Object name");
WRITEKEY(TSTRING, "OBJECT", objname, "Object name");
}
// BINNING / Binning
if(hbin != 1 || vbin != 1){
snprintf(buf, 79, "%d x %d", hbin, vbin);
WRITEKEY(fp, TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
WRITEKEY(TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
}
WRITEKEY(fp, TINT, "XBIN", &hbin, "Horizontal binning");
WRITEKEY(fp, TINT, "YBIN", &vbin, "Vertical binning");
WRITEKEY(TINT, "XBIN", &hbin, "Horizontal binning");
WRITEKEY(TINT, "YBIN", &vbin, "Vertical binning");
// OBSERVER / Observers
if(observers){
WRITEKEY(fp, TSTRING, "OBSERVER", observers, "Observers");
WRITEKEY(TSTRING, "OBSERVER", observers, "Observers");
}
// PROG-ID / Observation program identifier
if(prog_id){
WRITEKEY(fp, TSTRING, "PROG-ID", prog_id, "Observation program identifier");
WRITEKEY(TSTRING, "PROG-ID", prog_id, "Observation program identifier");
}
// AUTHOR / Author of the program
if(author){
WRITEKEY(fp, TSTRING, "AUTHOR", author, "Author of the program");
WRITEKEY(TSTRING, "AUTHOR", author, "Author of the program");
}
#ifdef USE_BTA
write_bta_data(fp);
#endif
check_wcs();
write_list(fp);
TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
TRYFITS(fits_close_file, fp);
return 0;

View File

@ -30,13 +30,7 @@ do{if(!test_headers){ int status = 0; \
fits_report_error(stderr, status); \
return -1;} \
}}while(0)
#define WRITEKEY(...) \
do{ if(test_headers){ \
print_fits_header(__VA_ARGS__); \
}else{ int status = 0; \
fits_write_key(__VA_ARGS__, &status); \
if(status) fits_report_error(stderr, status);\
}}while(0)
#define WRITEKEY(...) do{add_fits_header(__VA_ARGS__);}while(0)
void print_fits_header(fitsfile *fptr, int datatype, char *keyname,
void *value, char *comment);

435
defhdrs.c Normal file
View File

@ -0,0 +1,435 @@
/*
* defhdrs.c - read default headers from user file
*
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
/*
* Only these parameters are recognized:
SUBNET (instead of -E)
CAMMSGID (instead of -M)
INSTRUME
OBSERVER
PROG-ID
AUTHOR
XPIXELSZ
YPIXELSZ
IMSCALE
*/
#define _GNU_SOURCE
#include <math.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <fitsio.h>
#include "defhdrs.h"
#include "usage.h"
#include "macros.h"
#include "camtools.h"
// global keylist
static KeyList *FITS_keys = NULL;
double crval1 = -5e5, crval2 = -5e5, crpix1 = -5e5, crpix2 = -5e5;
double CD[2][2] = {{0.,0.}, {0.,0.}};
void get_defhdrs(char *fname){
mmapbuf *mmb = NULL;
if(!fname){ // find in default file: ~/$DEFCONF
const char *homedir;
if ((homedir = getenv("HOME")) == NULL){
homedir = getpwuid(getuid())->pw_dir;
}
size_t L = strlen(homedir) + strlen(DEFCONF) + 2;
fname = malloc(L);
snprintf(fname, L, "%s/%s", homedir, DEFCONF);
mmb = My_mmap(fname);
FREE(fname);
}else mmb = My_mmap(fname);
if(!mmb) return;
char *hdrs = strdup(mmb->data);
My_munmap(mmb);
char *nl = NULL;
while((nl = strchr(hdrs, '\n'))){
*nl = 0;
list_add_record(&FITS_keys, hdrs, 1);
hdrs = nl + 1;
}
if(*hdrs){ // last line in file didn't have newline
list_add_record(&FITS_keys, hdrs, 1);
}
}
/**
* Add headers from command line parameters
* something like `apogee_control <parameters> filename "KEY1 = VAL1 / comment" "KEYn = VALn / comment"
*/
void add_morehdrs(int argc, char **argv){
int i;
char buf[FLEN_CARD];
for(i = 0; i < argc; ++i){ // we should override parameters from default configuration file
char *dup = strdup(argv[i]);
char *eq = strchr(dup, '=');
if(eq){
*(eq++) = 0;
KeyList *found = list_find_key(FITS_keys, dup);
if(found) list_modify_key(FITS_keys, dup, eq, 2); // comments (if exists in new header) will be override too
else{
snprintf(buf, FLEN_CARD, "%-8s= %s", dup, eq);
list_add_record(&FITS_keys, buf, 2);
}
}else{ // comment or something else
list_add_record(&FITS_keys, dup, 2);
}
FREE(dup);
}
}
KeyList *list_get_end(KeyList *list){
if(!list) return NULL;
KeyList *first = list;
if(list->last) return list->last;
while(list->next) list = list->next;
first->last = list;
return list;
}
/**
* add record to keylist
* @param list (io) - pointer to root of list or NULL
* if *root == NULL, just created node will be placed there
* @param rec - data inserted
* @return pointer to created node
*/
KeyList *list_add_record(KeyList **list, char *rec, int immutable){
KeyList *node, *last;
if((node = (KeyList*) MALLOC(KeyList, 1)) == 0) return NULL; // allocation error
node->record = strdup(rec); // insert data
node->immutable = immutable;
DBG("add record %s", rec);
if(!node->record){
/// "Не могу скопировать данные"
WARNX(_("Can't copy data"));
return NULL;
}
if(list){
if(*list){ // there was root node - search last
last = list_get_end(*list);
last->next = node; // insert pointer to new node into last element in list
(*list)->last = node;
// DBG("last node %s", (*list)->last->record);
}else *list = node;
}
return node;
}
// compare keywords from `list` and `keyname`
int compare_keyw(KeyList *list, char *keyname){
if(!list || !keyname || !list->record) return 0;
size_t L = strlen(keyname);
if(strncmp(list->record, keyname, L) == 0){ // key found
char *ltr = list->record + L;
while(*ltr == ' ') ++ltr; // omit spaces
if(*ltr == '=') return 1; // only if there's equal sign after keyname!
}
return 0;
}
/**
* return record with given key or NULL
*/
KeyList *list_find_key(KeyList *list, char *keyname){
if(!list || !keyname) return NULL;
do{
if(compare_keyw(list, keyname)) return list;
list = list->next;
}while(list);
return NULL;
}
/**
* find value of key
* @return NULL if not found or strdup`ed value
*/
char *list_find_keyval(KeyList *l, char *key){
KeyList *list = list_find_key(l, key);
if(!list) return NULL;
char *rec = strdup(list->record);
char *val = strchr(rec, '=');
*val++ = 0;
char *com = strchr(val, '/');
if(com) *com = 0;
char *retval = strdup(val);
FREE(rec);
return retval;
}
int getdoubleval(double *val, KeyList *list, char *key){
char *v = list_find_keyval(list, key);
if(!v) return 0;
*val = strtod(v, NULL);
FREE(v);
return 1;
}
/**
* modify key value
* return NULL if given key is absent
*/
KeyList *list_modify_key(KeyList *list, char *key, char *newval, int immutable){
char buf[FLEN_CARD];
KeyList *rec = list_find_key(list, key);
if(!rec) return NULL;
if(rec->immutable > immutable) return NULL; // not modify immutable records
rec->immutable = immutable;
newval = strdup(newval);
char *comnt = strchr(newval, '/');
if(comnt){
*(comnt++) = 0;
}else{
comnt = strchr(rec->record, '/');
if(comnt) ++comnt;
}
if(comnt){
snprintf(buf, FLEN_CARD, "%-8s= %-21s/%s", key, newval, comnt);
}else{
snprintf(buf, FLEN_CARD, "%-8s= %s", key, newval);
}
FREE(rec->record);
FREE(newval);
DBG("modify record %s", buf);
rec->record = strdup(buf);
return rec;
}
void add_fits_header(int datatype, char *keyname, void *value, char *comment){
void _ub(char* r, void* p){snprintf(r, FLEN_CARD, "%20hhu", *(unsigned char*)p);}
void _b(char* r, void* p){snprintf(r, FLEN_CARD, "%20hhd", *(char*)p);}
void _us(char* r, void* p){snprintf(r, FLEN_CARD, "%20hu", *(unsigned short*)p);}
void _ui(char* r, void* p){snprintf(r, FLEN_CARD, "%20u", *(unsigned int*)p);}
void _ul(char* r, void* p){snprintf(r, FLEN_CARD, "%20lu", *(unsigned long*)p);}
void _s(char* r, void* p){snprintf(r, FLEN_CARD, "%20hd", *(short*)p);}
void _i(char* r, void* p){snprintf(r, FLEN_CARD, "%20d", *(int*)p);}
void _l(char* r, void* p){snprintf(r, FLEN_CARD, "%20ld", *(long*)p);}
void _ll(char* r, void* p){snprintf(r, FLEN_CARD, "%20lld", *(long long*)p);}
void _f(char* r, void* p){snprintf(r, FLEN_CARD, "%20.8f", *(float*)p);}
void _d(char* r, void* p){snprintf(r, FLEN_CARD, "%20.8f", *(double*)p);}
void _fc(char* r, void* p){snprintf(r, FLEN_CARD, "(%.8f, %.8f)",
((float*)p)[0], ((float*)p)[1]);}
void _dc(char* r, void* p){snprintf(r, FLEN_CARD, "(%.8f, %.8f)",
((double*)p)[0], ((double*)p)[1]);}
void _log(char* r, void* p){snprintf(r, FLEN_CARD, "'%s'", (int*)p ? "true" : "false");}
void _str(char* r, void* p){snprintf(r, FLEN_CARD, "'%s'", (char*)p);}
void _unk(char* r, void* p __attribute((unused))){sprintf(r, "unknown datatype");}
char tmp[FLEN_CARD], res[FLEN_CARD];
void (*__)(char*, void*);
switch(datatype){
case TBIT:
case TBYTE: __ = _ub; break;
case TSBYTE: __ = _b; break;
case TUSHORT: __ = _us; break;
case TUINT: __ = _ui; break;
case TULONG: __ = _ul; break;
case TSHORT: __ = _s; break;
case TINT: __ = _i; break;
case TLONG: __ = _l; break;
case TLONGLONG: __ = _ll; break;
case TFLOAT: __ = _f; break;
case TDOUBLE: __ = _d; break;
case TCOMPLEX: __ = _fc; break;
case TDBLCOMPLEX: __ = _dc; break;
case TLOGICAL: __ = _log; break;
case TSTRING: __ = _str; break;
default: __ = _unk;
}
__(res, value);
KeyList *rec = list_find_key(FITS_keys, keyname);
if(rec){
if(comment){
if(strlen(res) < 21)
snprintf(tmp, FLEN_CARD, "%-21s / %s", res, comment);
else
snprintf(tmp, FLEN_CARD, "%s / %s", res, comment);
}else snprintf(tmp, FLEN_CARD, "%s", res);
list_modify_key(FITS_keys, keyname, tmp, 0);
}else{
if(strlen(res) < 21)
snprintf(tmp, FLEN_CARD, "%-8s= %-20s", keyname, res);
else
snprintf(tmp, FLEN_CARD, "%-8s=%s", keyname, res);
snprintf(res, FLEN_CARD, "%s / %s", tmp, comment);
list_add_record(&FITS_keys, res, 0);
}
}
/**
* free list memory & set it to NULL
*/
void list_free(KeyList **list){
KeyList *node = *list, *next;
if(!list || !*list) return;
do{
next = node->next;
FREE(node->record);
free(node);
node = next;
}while(node);
*list = NULL;
}
void free_fits_list(){ list_free(&FITS_keys); }
/*
void list_print(KeyList *list){
while(list){
printf("%s\n", list->record);
list = list->next;
}
}
void show_list(){
list_print(FITS_keys);
}
*/
void write_list(fitsfile *fp){
if(FITS_keys){ // there's keys
KeyList *records = FITS_keys;
while(records){
char *rec = records->record;
records = records->next;
if(strncmp(rec, "SIMPLE", 6) == 0 || strncmp(rec, "EXTEND", 6) == 0) // key "file does conform ..."
continue;
// comment of obligatory key in FITS head
else if(strncmp(rec, "COMMENT FITS", 14) == 0 || strncmp(rec, "COMMENT and Astrophysics", 26) == 0)
continue;
else if(strncmp(rec, "NAXIS", 5) == 0 || strncmp(rec, "BITPIX", 6) == 0) // NAXIS, NAXISxxx, BITPIX
continue;
if(!test_headers){
int status = 0;
fits_write_record(fp, rec, &status);
if(status) fits_report_error(stderr, status);
}else
printf("%s\n", rec);
}
}
}
/**
* Check if user tell some information about WCS and add it into headers
*/
void check_wcs(){
double cd = -5e5, crot = -5e5, rot0 = -5e5;
char buf[FLEN_CARD];
// first correct scale: user value SCALE will fix parameter imscale
if(imscale < 0.) getdoubleval(&imscale, FITS_keys, "SCALE");
if(imscale < 0.){
imscale = 180.*3600./M_PI / TELFOCUS / 1000000. * sqrt(pixX*pixY); // default system value
}
snprintf(buf, FLEN_CARD, "%.4f x %.4f", imscale * hbin, imscale * vbin);
WRITEKEY(TSTRING, "IMSCALE", buf, "image scale (''/Pix x ''/Pix)");
int cnt = getdoubleval(&crval1, FITS_keys, "CRVAL1");
cnt += getdoubleval(&crval2, FITS_keys, "CRVAL1");
cnt += getdoubleval(&crpix1, FITS_keys, "CRPIX1");
cnt += getdoubleval(&crpix2, FITS_keys, "CRPIX2");
cnt += getdoubleval(&cd, FITS_keys, "CD1_1");
cnt += getdoubleval(&crot, FITS_keys, "CROTA2");
cnt += getdoubleval(&rot0, FITS_keys, "ROT0");
DBG("cnt = %d", cnt);
if(!cnt) return;
int wcs = 2;
WRITEKEY(TINT, "WCSAXIS", &wcs, "Number of WCS axes");
WRITEKEY(TSTRING, "CTYPE1", "RA---TAN", "RA-Gnomic projection");
WRITEKEY(TSTRING, "CUNIT1", "deg", "RA units - degrees");
WRITEKEY(TSTRING, "CTYPE2", "DEC---TAN", "Decl-Gnomic projection");
WRITEKEY(TSTRING, "CUNIT2", "deg", "Decl units - degrees");
// CRVAL1 = / RA of reference pixel
if(crval1 > -4e-5)
WRITEKEY(TDOUBLE, "CRVAL1", &crval1, "RA of reference pixel");
else crval1 = 0;
// CRVAL2 = / Decl of reference pixel
if(crval2 > -4e-5)
WRITEKEY(TDOUBLE, "CRVAL2", &crval2, "Decl of reference pixel");
else crval2 = 0;
//CRPIX1 = / X reference pixel
if(crpix1 > -4e-5)
WRITEKEY(TDOUBLE, "CRPIX1", &crpix1, "X reference pixel");
else crpix1 = 0;
//CRPIX2 = / Y reference pixel
if(crpix2 > -4e-5)
WRITEKEY(TDOUBLE, "CRPIX2", &crpix2, "Y reference pixel");
else crpix2 = 0;
cnt = 0;
if(cd > -4e5){
++cnt;
WRITEKEY(TDOUBLE, "CD1_1", &cd, "rotation matrix coefficient [1,1]");
CD[0][0] = cd;
}
if(getdoubleval(&cd, FITS_keys, "CD1_2")){
++cnt;
WRITEKEY(TDOUBLE, "CD1_2", &cd, "rotation matrix coefficient [1,2]");
CD[0][1] = cd;
}
if(getdoubleval(&cd, FITS_keys, "CD2_1")){
++cnt;
WRITEKEY(TDOUBLE, "CD2_1", &cd, "rotation matrix coefficient [2,1]");
CD[1][0] = cd;
}
if(getdoubleval(&cd, FITS_keys, "CD2_2")){
++cnt;
WRITEKEY(TDOUBLE, "CD2_2", &cd, "rotation matrix coefficient [2,2]");
CD[1][1] = cd;
}
if(cnt == 4) return;
// no coefficients - use CROTA & CDELT
cnt = 0;
if(crot > -4e5){
++cnt;
DBG("crot: %g", crot);
WRITEKEY(TDOUBLE, "CROTA2", &crot, "North rotation angle");
}
if(getdoubleval(&crot, FITS_keys, "CDELT1")){
++cnt;
WRITEKEY(TDOUBLE, "CDELT1", &crot, "X axis scale");
getdoubleval(&crot, FITS_keys, "CDELT2");
WRITEKEY(TDOUBLE, "CDELT2", &crot, "Y axis scale"); // use CDELT1 if user omits CDELT2
}
if(cnt == 2) return;
// still no coefficients - try to calculate CDx_x by user data
double parangle, rotangle;
if(rot0 < -4e5) return; // no values
if(!getdoubleval(&parangle, FITS_keys, "PARANGLE")) return;
if(!getdoubleval(&rotangle, FITS_keys, "VAL_P")) return;
double s, c, scx = imscale / 3600. * hbin, scy = imscale / 3600. * vbin;
if(rot0 < 0){ // left-handed
crot = (-rot0 + parangle - rotangle)*M_PI/180;
DBG("crot = %g", crot*180/M_PI);
sincos(crot, &s, &c);
CD[0][0] = -scx * c; CD[0][1] = scy * s;
CD[1][0] = scx * s; CD[1][1] = scy * c;
}else{ // right-handed
crot = (rot0 - parangle + rotangle)*M_PI/180;
sincos(crot, &s, &c);
CD[0][0] = scx * c; CD[0][1] = -scy * s;
CD[1][0] = scx * s; CD[1][1] = scy * c;
}
WRITEKEY(TDOUBLE, "CD1_1", &CD[0][0], "rotation matrix coefficient [1,1]");
WRITEKEY(TDOUBLE, "CD1_2", &CD[0][1], "rotation matrix coefficient [1,2]");
WRITEKEY(TDOUBLE, "CD2_1", &CD[1][0], "rotation matrix coefficient [2,1]");
WRITEKEY(TDOUBLE, "CD2_2", &CD[1][1], "rotation matrix coefficient [2,2]");
}

52
defhdrs.h Normal file
View File

@ -0,0 +1,52 @@
/*
* defhdrs.h
*
* Copyright 2016 Edward V. Emelianov <eddy@sao.ru, edward.emelianoff@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#pragma once
#ifndef __DEFHDRS_H__
#define __DEFHDRS_H__
extern double crval1, crval2, crpix1, crpix2, CD[2][2]; // global coefficients for WCS
typedef struct klist_{
char *record;
int immutable; // not modify record if old value of `immutable` > new value
struct klist_ *next;
struct klist_ *last;
} KeyList;
void list_free(KeyList **list);
void free_fits_list();
KeyList *list_add_record(KeyList **list, char *rec, int immutable);
KeyList *list_find_key(KeyList *list, char *key);
KeyList *list_modify_key(KeyList *list, char *key, char *newval, int immutable);
KeyList *list_get_end(KeyList *list);
/*
void list_print(KeyList *list);
void show_list();
*/
void add_fits_header(int datatype, char *keyname, void *value, char *comment);
void write_list(fitsfile *fp);
void get_defhdrs(char *fname);
void add_morehdrs(int argc, char **argv);
void check_wcs();
#endif // __DEFHDRS_H__

View File

@ -172,15 +172,16 @@ mmapbuf *My_mmap(char *filename){
char *ptr;
size_t Mlen;
struct stat statbuf;
if(!filename) ERRX(_("No filename given!"));
DBG("Try to mmap %s", filename);
if(!filename) return NULL;
if((fd = open(filename, O_RDONLY)) < 0)
ERR(_("Can't open %s for reading"), filename);
return NULL;
if(fstat (fd, &statbuf) < 0)
ERR(_("Can't stat %s"), filename);
return NULL;
Mlen = statbuf.st_size;
if((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
ERR(_("Mmap error for input"));
if(close(fd)) ERR(_("Can't close mmap'ed file"));
return NULL;
if(close(fd)) return NULL;
mmapbuf *ret = MALLOC(mmapbuf, 1);
ret->data = ptr;
ret->len = Mlen;
@ -189,7 +190,7 @@ mmapbuf *My_mmap(char *filename){
void My_munmap(mmapbuf *b){
if(munmap(b->data, b->len))
ERR(_("Can't munmap"));
WARN(_("Can't munmap"));
FREE(b);
}

View File

@ -29,6 +29,7 @@
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
#include "defhdrs.h"
#include "usage.h"
#include "camtools.h"
#ifdef USE_BTA
@ -44,7 +45,7 @@
#define TMBUFSIZ 40 // time string buffer length
char *pidfilename = "/tmp/takepic.pid"; // pidfile
char *pidfilename = "/tmp/apogee_control.pid"; // pidfile
char tm_buf[TMBUFSIZ]; // time string buffer
@ -692,6 +693,7 @@ returning:
restore_signals();
DBG("free buffers & close files");
free(buf);
free_fits_list();
if(f_tlog) fclose(f_tlog);
if(f_statlog) fclose(f_statlog);
#ifdef IMAGEVIEW

View File

@ -21,7 +21,9 @@
#pragma once
#ifndef __TAKEPIC_H__
#define __TAKEPIC_H__
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 501
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
@ -56,40 +58,24 @@
* SAO longitude 41 26 29.175
* SAO latitude 43 39 12.7
* SAO altitude 2070
* BTA focal ratio 24.024 m
*/
#ifndef TELLAT
#define TELLAT 43.6535278
#define TELLAT (43.6535278)
#endif
#ifndef TELLONG
#define TELLONG 41.44143375
#define TELLONG (41.44143375)
#endif
#ifndef TELALT
#define TELALT 2070.0
#define TELALT (2070.0)
#endif
#ifndef TELFOCUS
#define TELFOCUS (24.024)
#endif
// filename for default headers (in ~)
#ifndef DEFCONF
#define DEFCONF "apogee_hdrs.fits"
#endif
/*
#define _(String) gettext(String)
#define gettext_noop(String) String
#define N_(String) gettext_noop(String)
// ÒÅÖÉÍ ÏÔÌÁÄËÉ, -DEBUG
#ifdef EBUG
#define RED "\033[1;32;41m"
#define GREEN "\033[5;30;42m"
#define OLDCOLOR "\033[0;0;0m"
#define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
#define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n");} while(0)
#define ERR(...) DBG(__VA_ARGS__)
#else
#define FNAME() do{}while(0)
#define DBG(...) do{}while(0)
#define ERR(...) do{fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n");} while(0)
#endif //EBUG
*/
extern int test_headers;
extern const char *__progname;
@ -98,14 +84,4 @@ extern const char *__progname;
printf(format, ## args); \
printf("\n");}while(0)
/*
#define warnc(c, format, args...) \
warnx(format ": %s", ## args, strerror(c))
long r;
#define TRYFUNC(f, ...) \
do{ if((r = f(__VA_ARGS__))) \
warnc(-r, #f "() failed"); \
}while(0)
*/
#endif // __TAKEPIC_H__

56
usage.c
View File

@ -21,6 +21,7 @@
#include "usage.h"
#include "macros.h"
#include "defhdrs.h"
Apn_Filter Tturret = Apn_Filter_FW50_7S; // turrer type
int
@ -43,6 +44,7 @@ char
,*author = NULL // author of program
,*subnet = NULL // subnet for ethernet camera discovery
,*cammsgid = NULL // MSG-ID of camera
,*defhdr_filename = NULL // name of file with default headers
;
int
exptime = -1 // exposition time (in ms), -1 means no exposition
@ -65,7 +67,11 @@ int
,flipY = 0 // flip image around Y axe (horizontal flip)
,histry = 0 // write history at expositions
;
double temperature = -25.; // setpoint of temperature
double
temperature = -25. // setpoint of temperature
,imscale = -1. // image scale (''/pix) given by user
;
int shutter = 1; // object frame == 1, dark frame == 0
@ -125,31 +131,37 @@ void usage(char *fmt, ...){
}
va_end(ap);
// "éÓÐÏÌØÚÏ×ÁÎÉÅ:\t%s [ÏÐÃÉÉ] [ÐÒÅÆÉËÓ ×ÙÈÏÄÎÙÈ ÆÁÊÌÏ×]\n"
printf(_("Usage:\t%s [options] [output files prefix]\n"),
printf(_("Usage:\t%s [options] [output files prefix] [additional headers]\n"),
__progname);
// "\tïÐÃÉÉ:\n"
printf(_("\tOptions:\n"));
printf("\t-A,\t--author=author\t\t%s\n",
// "Á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ"
_("program author"));
printf("\t-b,\t--defhdr=filename\t%s\n",
// "ÉÍÑ ÆÁÊÌÁ Ó ÚÁÇÏÌÏ×ËÁÍÉ ÐÏ ÕÍÏÌÞÁÎÉÀ"
_("file with default headers"));
printf("\t-c,\t--cooler-off\t\t%s\n",
// "ÏÔËÌÀÞÉÔØ ÈÏÌÏÄÉÌØÎÉË"
_("Set cooler off"));
_("set cooler off"));
printf("\t-C,\t--imscale\t\t%s\n",
// "ÍÁÓÛÔÁÂ ÉÚÏÂÒÁÖÅÎÉÑ ÂÅÚ ÂÉÎÎÉÎÇÁ"
_("image scale without binning"));
printf("\t-d,\t--dark\t\t\t%s\n",
// "ÎÅ ÏÔËÒÙ×ÁÔØ ÚÁÔ×ÏÒ ÐÒÉ ÜËÓÐÏÚÉÃÉÉ (\"ÔÅÍÎÏ×ÙÅ\")"
_("not open shutter when exposing (\"dark frames\")"));
printf("\t-D,\t--display-image\t\t%s\n",
// "ïÔÏÂÒÁÚÉÔØ ÎÁ ÜËÒÁÎÅ ÐÏÌÕÞÅÎÎÏÅ ÉÚÏÂÒÁÖÅÎÉÅ"
_("Display last image"));
_("display last image"));
printf("\t-E,\t--ether-subnet\t\t%s\n",
// "ðÏÄÓÅÔØ ÄÌÑ ÐÏÉÓËÁ ethernet-ËÁÍÅÒÙ"
_("Subnet fot ethernet camera discovery"));
_("subnet fot ethernet camera discovery"));
printf("\t-f,\t--no-flash\t\t%s\n",
// "ÎÅ ÚÁÓ×ÅÞÉ×ÁÔØ ÍÁÔÒÉÃÕ ÐÅÒÅÄ ÜËÓÐÏÚÉÃÉÅÊ"
_("Don't flash CCD chip before expose"));
_("don't flash CCD chip before expose"));
printf("\t-F,\t--fan-speed=F\t\t%s\n",
// "õÓÔÁÎÏ×ÉÔØ ÓËÏÒÏÓÔØ ×ÅÎÔÉÌÑÔÏÒÏ× × F (0..3)"
_("Set fan speed to F (0..3)"));
_("set fan speed to F (0..3)"));
printf("\t-g,\t--wheel-get\t\t%s\n",
// ÐÏÌÕÞÉÔØ Ó×ÅÄÅÎÉÑ Ï ÔÕÒÅÌÉ
_("get turret's parameters"));
@ -265,7 +277,7 @@ void usage(char *fmt, ...){
void parse_args(int argc, char **argv){
FNAME();
int i;
char short_options[] = "A:cdDE:fF:gG:H:h:I:i:LlM:N:n:O:o:P:p:Rr:SsTt:v:Ww:x:X:Y:";
char short_options[] = "A:b:cC:dDE:fF:gG:H:h:I:i:LlM:N:n:O:o:P:p:Rr:SsTt:v:Ww:x:X:Y:";
struct option long_options[] = {
/* { name, has_arg, flag, val }, ÇÄÅ:
* name - name of long parameter
@ -276,10 +288,12 @@ void parse_args(int argc, char **argv){
* !!! last string - for zeros !!!
*/
{"author", 1, 0, 'A'},
{"defhdr", 1, 0, 'b'},
{"cooler-off", 0, 0, 'c'},
{"imscale", 1, 0, 'C'},
{"dark", 0, 0, 'd'},
{"display-image",0, 0, 'D'},
{"--ether-subnet",1,0, 'E'},
{"ether-subnet",1, 0, 'E'},
{"no-flash", 0, 0, 'f'},
{"fan-speed", 1, 0, 'F'},
{"wheel-get", 0, 0, 'g'},
@ -337,6 +351,9 @@ void parse_args(int argc, char **argv){
// "á×ÔÏÒ ÐÒÏÇÒÁÍÍÙ: %s"
info(_("Program author: %s"), author);
break;
case 'b':
defhdr_filename = strdup(optarg);
break;
case 'c':
only_turret = FALSE;
set_T = TRUE;
@ -344,6 +361,13 @@ void parse_args(int argc, char **argv){
info(_("Set cooler off"));
cooler_off = TRUE;
break;
case 'C':
imscale = atof(optarg);
if(imscale < 0.){
// "IMSCALE ÄÏÌÖÎÏ ÂÙÔØ ÂÏÌØÛÅ ÎÕÌÑ"
usage(_("IMSCALE should be greater than zero"));
}
break;
case 'd':
shutter = 0;
// "óßÅÍËÁ ÔÅÍÎÏ×ÙÈ"
@ -427,7 +451,7 @@ void parse_args(int argc, char **argv){
break;
case 'M':
cammsgid = strdup(optarg);
info("MSG_ID: %s", cammsgid);
info("CAMMSGID: %s", cammsgid);
break;
case 'N':
only_turret = FALSE;
@ -559,16 +583,18 @@ void parse_args(int argc, char **argv){
if(argc == 0){
save_image = FALSE;
}
else{
else if(!strchr(argv[0], '=') && !strchr(argv[0], ' ')){ // argv[0] is a filename
outfile = argv[0];
argc--;
argv++;
}
if(argc > 0){
// "éÇÎÏÒÉÒÕÀ ÁÒÇÕÍÅÎÔ[Ù]:\n"
printf(_("Ignore argument[s]:\n"));
get_defhdrs(defhdr_filename);
if(argc > 0){ // additional headers
// "äÏÐÏÌÎÉÔÅÌØÎÙÅ ÚÁÇÏÌÏ×ËÉ:\n"
info(_("Additional headers"));
for (i = 0; i < argc; i++)
warnx("%s ", argv[i]);
info("%s ", argv[i]);
}
add_morehdrs(argc, argv);
if(Shtr != -1) only_turret = FALSE;
}

View File

@ -61,7 +61,10 @@ extern int
,flipY
,histry
;
extern double temperature;
extern double
temperature
,imscale
;
extern bool
only_T
@ -87,6 +90,7 @@ extern char
,*author
,*subnet
,*cammsgid
,*defhdr_filename
;
void usage(char *fmt, ...);
void parse_args(int argc, char **argv);