fix some bugs

This commit is contained in:
eddyem 2020-01-23 17:33:32 +03:00
parent 4da483b33a
commit ec25bc36c7
21 changed files with 3849 additions and 3454 deletions

1
Apogee_control.cflags Normal file
View File

@ -0,0 +1 @@
-std=c17

7
Apogee_control.config Normal file
View File

@ -0,0 +1,7 @@
// Add predefined macros for your project here. For example:
// #define THE_ANSWER 42
#define IMAGEVIEW
#define EBUG
#define USEPNG
#define USERAW

1
Apogee_control.creator Normal file
View File

@ -0,0 +1 @@
[General]

256
Apogee_control.creator.user Normal file
View File

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.1, 2020-01-10T12:15:02. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{cf63021e-ef53-49b0-b03b-2f2570cdf3b6}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">KOI8-R</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">false</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">1</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">2</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
<value type="bool" key="ClangCodeModel.UseGlobalConfig">false</value>
<value type="QString" key="ClangCodeModel.WarningConfigId">{44e88e9a-8179-42ea-8aad-1bea96363cc6}</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">{44e88e9a-8179-42ea-8aad-1bea96363cc6}</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs">
<value type="QString">/home/eddy/tmp/apogee_control/Apogee_control.creator</value>
</valuelist>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{91347f2c-5221-46a7-80b1-0a054ca02f79}</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/tmp/apogee_control</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">По умолчанию</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/eddy/tmp/apogee_control</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<valuelist type="QVariantList" key="GenericProjectManager.GenericMakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="GenericProjectManager.GenericMakeStep.Clean">false</value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeArguments"></value>
<value type="QString" key="GenericProjectManager.GenericMakeStep.MakeCommand"></value>
<value type="bool" key="GenericProjectManager.GenericMakeStep.OverrideMakeflags">false</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Сборка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericMakeStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Очистка</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">cmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">cmake</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">GenericProjectManager.GenericBuildConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Развёртывание</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Конфигурация развёртывания</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Особая программа</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="RunConfiguration.Arguments"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory"></value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default"></value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

1
Apogee_control.cxxflags Normal file
View File

@ -0,0 +1 @@
-std=c++17

16
Apogee_control.files Normal file
View File

@ -0,0 +1,16 @@
airmass.c
am.c
bta_print.c
bta_print.h
bta_shdata.c
bta_shdata.h
camtools.c
camtools.h
defhdrs.c
defhdrs.h
macros.c
macros.h
takepic.c
takepic.h
usage.c
usage.h

2
Apogee_control.includes Normal file
View File

@ -0,0 +1,2 @@
.
./image_view_module

View File

@ -1,25 +1,24 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 2.6)
set(PROJ apogee_control) set(PROJ apogee_control)
project(${PROJ})
set(VERSION "0.2.0") set(VERSION "0.2.0")
set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_COLOR_MAKEFILE ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
if(DEFINED EBUG) if(DEFINED EBUG)
add_definitions(-DEBUG) add_definitions(-DEBUG)
set(CFLAGS ${CFLAGS} -Werror)
message("CFLAGS: ${CFLAGS}")
set(CMAKE_VERBOSE_MAKEFILE ON)
endif() endif()
if(DEFINED CMAKE_INSTALL_PREFIX AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
set(CMAKE_INSTALL_PREFIX "/usr")
project(${PROJ} VERSION ${PROJ_VERSION} LANGUAGES C CXX) endif()
message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}")
#if(DEFINED CMAKE_INSTALL_PREFIX AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
# set(CMAKE_INSTALL_PREFIX "/usr")
#endif()
if(NOT DEFINED LOCALEDIR) if(NOT DEFINED LOCALEDIR)
set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale) set(LOCALEDIR ${CMAKE_INSTALL_PREFIX}/share/locale)
endif() endif()
set(SOURCES defhdrs.c 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(DEFINED USE_BTA AND USE_BTA STREQUAL "yes") if(NOT DEFINED NOBTA)
set(SOURCES ${SOURCES} bta_print.c) set(SOURCES ${SOURCES} bta_print.c bta_shdata.c)
add_definitions(-DUSE_BTA) add_definitions(-DUSE_BTA)
endif() endif()
if(DEFINED TELALT) if(DEFINED TELALT)
@ -45,26 +44,26 @@ endif()
add_definitions(-DTHREAD_NUMBER=${PROCESSOR_COUNT}) add_definitions(-DTHREAD_NUMBER=${PROCESSOR_COUNT})
message("In multithreaded operations will use ${PROCESSOR_COUNT} threads") message("In multithreaded operations will use ${PROCESSOR_COUNT} threads")
set(LCPATH ${CMAKE_CURRENT_SOURCE_DIR}/locale/ru) set(LCPATH ${CMAKE_CURRENT_SOURCE_DIR}/locale/ru)
set(CFLAGS -O2 -Wextra -Wall -Werror -W -std=gnu99) set(CFLAGS ${CFLAGS} -O2 -Wextra -Wall -W -std=gnu99)
#set(CFLAGS ${CFLAGS} -O2 -std=gnu99)
set(PO_FILE ${LCPATH}/messages.po) set(PO_FILE ${LCPATH}/messages.po)
set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo) set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo)
set(RU_FILE ${LCPATH}/ru.po) set(RU_FILE ${LCPATH}/ru.po)
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
set(MODULES cfitsio>=3.0 apogeec>=1.71 libusb>=0.1.10)
# find CFITSIO if(NOT DEFINED NOBTA)
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) #set(MODULES ${MODULES} sla)
FIND_PACKAGE(CFITSIO REQUIRED) target_link_libraries(${PROJ} crypt sofa_c)
set(MODULES apogeec>=1.71 libusb>=0.1.10)
if(DEFINED USE_BTA AND USE_BTA STREQUAL "yes")
set(MODULES ${MODULES} sla)
endif() endif()
if(DEFINED USE_PNG AND USE_PNG STREQUAL "yes") if(DEFINED USEPNG)
set(MODULES ${MODULES} libpng>=1.2) set(MODULES ${MODULES} libpng>=1.2)
add_definitions(-DUSEPNG) add_definitions(-DUSEPNG)
endif() endif()
pkg_check_modules(${PROJ} REQUIRED ${MODULES}) pkg_check_modules(${PROJ} REQUIRED ${MODULES})
if(DEFINED USE_RAW AND USE_RAW STREQUAL "yes") if(DEFINED USERAW)
add_definitions(-DUSERAW) add_definitions(-DUSERAW)
endif() endif()
@ -75,23 +74,22 @@ if(OPENMP_FOUND)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif() endif()
add_executable(${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE}) include_directories(${${PROJ}_INCLUDE_DIRS} image_view_module)
include_directories(${${PROJ}_INCLUDE_DIRS} ${CFITSIO_INCLUDE_DIR} image_view_module)
link_directories(${${PROJ}_LIBRARY_DIRS}) link_directories(${${PROJ}_LIBRARY_DIRS})
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" -DPACKAGE_VERSION=\"${VERSION}\" add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" -DPACKAGE_VERSION=\"${VERSION}\"
-DGETTEXT_PACKAGE=\"${PROJ}\" -DPROJNAME=\"${PROJ}\") -DGETTEXT_PACKAGE=\"${PROJ}\" -DPROJNAME=\"${PROJ}\")
if(DEFINED USE_IMAGEVIEW AND USE_IMAGEVIEW STREQUAL "yes") if(NOT DEFINED NOIMAGEVIEW)
add_subdirectory(image_view_module) add_subdirectory(image_view_module)
endif() endif()
if(IMAGEVIEW_FOUND) if(IMAGEVIEW_FOUND)
message("Found OpenGL. Will use ${IMLIB} to show data") message("Found OpenGL. Will use ${IMLIB} to show data")
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
target_link_libraries(${PROJ} ${IMLIB} ${X11_LIBRARIES} ${${PROJ}_LIBRARIES} ${CFITSIO_LIBRARIES} -lm) target_link_libraries(${PROJ} ${X11_LIBRARIES} ${${PROJ}_LIBRARIES} -lm ${IMLIB})
add_definitions(-DIMAGEVIEW) add_definitions(-DIMAGEVIEW)
else() else()
message("Will compile without image view module") message("Will compile without image view module")
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} ${CFITSIO_LIBRARIES} -lm) target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} -lm)
endif() endif()
# Installation of the program # Installation of the program

View File

@ -28,38 +28,67 @@
* file_name - name of file to write to, * file_name - name of file to write to,
* "-" - stdout (default) * "-" - stdout (default)
*/ */
#include "bta_shdata.h"
#include "takepic.h"
#include "camtools.h"
#include "bta_print.h" #include "bta_print.h"
#include "macros.h" #include "bta_shdata.h"
#include "usage.h" // command line parameters #include "camtools.h"
#include "defhdrs.h" #include "defhdrs.h"
#include <slamac.h> // SLA macros #include "macros.h"
#include "takepic.h"
#include "usage.h" // command line parameters
#include <sofa.h>
//#include <slamac.h> // SLA macros
#ifndef DR2S
#define DR2S 1.3750987083139757010431557155385240879777313391975e4
#endif
/*
extern void sla_amp(double*, double*, double*, double*, double*, double*); extern void sla_amp(double*, double*, double*, double*, double*, double*);
void slaamp(double ra, double da, double date, double eq, double *rm, double *dm ){ void slaamp(double ra, double da, double date, double eq, double *rm, double *dm ){
double r = ra, d = da, mjd = date, equi = eq; double r = ra, d = da, mjd = date, equi = eq;
sla_amp(&r, &d, &mjd, &equi, rm, dm); sla_amp(&r, &d, &mjd, &equi, rm, dm);
} }
const double jd0 = 2400000.5; // JD for MJD==0 const double jd0 = 2400000.5; // JD for MJD==0
*/
/** /**
* convert apparent coordinates (nowadays) to mean (JD2000) * convert apparent coordinates (nowadays) to mean (JD2000)
* appRA, appDecl in seconds * appRA, appDecl in seconds
* r, d in seconds * r, d in seconds
*/ */
void calc_mean(double appRA, double appDecl, double *r, double *d){ void calc_mean(double appRA, double appDecl, double *r, double *dc){
double ra, dec; double ra=0., dec=0., utc1, utc2, tai1, tai2, tt1, tt2, fd, eo, ri;
appRA *= DS2R; int y, m, d, H, M;
appDecl *= DAS2R; DBG("appRa: %g'', appDecl'': %g", appRA, appDecl);
//DBG("appRa: %g, appDecl: %g", appRA, appDecl); appRA *= DS2R;
double mjd = JDate - jd0; appDecl *= DAS2R;
slaamp(appRA, appDecl, mjd, 2000.0, &ra, &dec); /* double mjd = JDate - jd0;
ra *= DR2S; slaamp(appRA, appDecl, mjd, 2000.0, &ra, &dec);
dec *= DR2AS; ra *= DR2S;
if(r) *r = ra; dec *= DR2AS;
if(d) *d = dec; DBG("SLALIB: r=%g'', d=%g''", ra, dec);
ra = 0.; dec = 0.;*/
// SOFA
#define SOFA(f, ...) do{if(f(__VA_ARGS__)){WARNX("Error in " #f); goto rtn;}}while(0)
// 1. convert system JDate to UTC
SOFA(iauJd2cal, JDate, 0., &y, &m, &d, &fd);
fd *= 24.;
H = (int)fd;
fd = (fd - H)*60.;
M = (int)fd;
fd = (fd - M)*60.;
SOFA(iauDtf2d, "UTC", y, m, d, H, M, fd, &utc1, &utc2);
SOFA(iauUtctai, utc1, utc2, &tai1, &tai2);
SOFA(iauTaitt, tai1, tai2, &tt1, &tt2);
iauAtic13(appRA, appDecl, tt1, tt2, &ri, &dec, &eo);
ra = iauAnp(ri + eo);
ra *= DR2S;
dec *= DR2AS;
DBG("SOFA: r=%g'', d=%g''", ra, dec);
#undef SOFA
rtn:
if(r) *r = ra;
if(dc) *dc = dec;
} }
char comment[FLEN_CARD]; char comment[FLEN_CARD];
@ -67,291 +96,291 @@ char comment[FLEN_CARD];
#define FTKEY(...) WRITEKEY(__VA_ARGS__, comment) #define FTKEY(...) WRITEKEY(__VA_ARGS__, comment)
#define WRITEHIST(fp) \ #define WRITEHIST(fp) \
do{ if(test_headers){printf("HISTORY: %s\n", comment);}else{ \ do{ if(test_headers){printf("HISTORY: %s\n", comment);}else{ \
int status = 0; \ int status = 0; \
fits_write_history(fp, comment, &status); \ fits_write_history(fp, comment, &status); \
if(status) fits_report_error(stderr, status);\ if(status) fits_report_error(stderr, status);\
}}while(0) }}while(0)
int shm_ready = FALSE; // BTA shm_get int shm_ready = FALSE; // BTA shm_get
// calculate airmass // calculate airmass
extern void calc_airmass( extern void calc_airmass(
// in // in
double daynum, // Day number from beginning of year, 0 = midnight Jan 1 double daynum, // Day number from beginning of year, 0 = midnight Jan 1
double relhumid,// Relative humidity in percent double relhumid,// Relative humidity in percent
double p0, // local pressure in mmHg double p0, // local pressure in mmHg
double t0, // temperature in kelvins double t0, // temperature in kelvins
double z, // zenith distance in degr double z, // zenith distance in degr
// out // out
double *am, // AIRMASS double *am, // AIRMASS
double *acd, // column density double *acd, // column density
double *wcd, // water vapor column density double *wcd, // water vapor column density
double *wam // water vapor airmass double *wam // water vapor airmass
); );
static char buf[1024]; static char buf[1024];
char *time_asc(double t){ char *time_asc(double t){
int h, m; int h, m;
double s; double s;
char *str = ""; char *str = "";
h = (int)(t/3600.); h = (int)(t/3600.);
if(t < 0.){ t = -t; str = "-";} if(t < 0.){ t = -t; str = "-";}
m = (int)((t - (double)h*3600.)/60.); m = (int)((t - (double)h*3600.)/60.);
s = t - (double)h*3600. - (double)m*60.; s = t - (double)h*3600. - (double)m*60.;
h %= 24; h %= 24;
if(s>59) s=59; if(s>59) s=59;
sprintf(buf, "%s%dh:%02dm:%04.1fs", str, h,m,s); sprintf(buf, "%s%dh:%02dm:%04.1fs", str, h,m,s);
return buf; return buf;
} }
char *angle_asc(double a){ char *angle_asc(double a){
char s; char s;
int d, min; int d, min;
double sec; double sec;
if (a >= 0.) if (a >= 0.)
s = '+'; s = '+';
else{ else{
s = '-'; a = -a; s = '-'; a = -a;
} }
d = (int)(a/3600.); d = (int)(a/3600.);
min = (int)((a - (double)d*3600.)/60.); min = (int)((a - (double)d*3600.)/60.);
sec = a - (double)d*3600. - (double)min*60.; sec = a - (double)d*3600. - (double)min*60.;
d %= 360; d %= 360;
if(sec>59.9) sec=59.9; if(sec>59.9) sec=59.9;
sprintf(buf, "%c%d:%02d':%04.1f''", s,d,min,sec); sprintf(buf, "%c%d:%02d':%04.1f''", s,d,min,sec);
return buf; return buf;
} }
typedef struct{ typedef struct{
double JD; // JDate double JD; // JDate
double Azimuth; // val_A double Azimuth; // val_A
double Zenith; // val_Z double Zenith; // val_Z
double P2; // val_P double P2; // val_P
double Wind; // val_Wnd double Wind; // val_Wnd
//double Tmir; // //double Tmir; //
} BTA_PARAMS; } BTA_PARAMS;
typedef struct _BTA_Que{ typedef struct _BTA_Que{
BTA_PARAMS *data; BTA_PARAMS *data;
struct _BTA_Que *next; struct _BTA_Que *next;
struct _BTA_Que *last; struct _BTA_Que *last;
} BTA_Queue; } BTA_Queue;
void write_bta_queue(fitsfile *fp); void write_bta_queue(fitsfile *fp);
BTA_Queue *bta_queue = NULL; BTA_Queue *bta_queue = NULL;
void write_bta_data(fitsfile *fp){ void write_bta_data(fitsfile *fp){
char *val; char *val;
double dtmp; double dtmp;
//char buf[FLEN_CARD]; //char buf[FLEN_CARD];
time_t t_now = time(NULL); time_t t_now = time(NULL);
struct tm *tm_ut, *tm_loc; struct tm *tm_ut, *tm_loc;
tm_ut = gmtime(&t_now); tm_ut = gmtime(&t_now);
tm_loc = localtime(&t_now); tm_loc = localtime(&t_now);
if(!shm_ready){ if(!shm_ready){
if(!get_shm_block(&sdat, ClientSide)) return; if(!get_shm_block(&sdat, ClientSide)) return;
else shm_ready = TRUE; else shm_ready = TRUE;
} }
if(!check_shm_block(&sdat)) return; if(!check_shm_block(&sdat)) return;
/* /*
* Observatory parameters * Observatory parameters
*/ */
// TELESCOP / Telescope name // TELESCOP / Telescope name
CMNT("Telescope name"); CMNT("Telescope name");
FTKEY(TSTRING, "TELESCOP", "BTA 6m telescope"); FTKEY(TSTRING, "TELESCOP", "BTA 6m telescope");
// ORIGIN / organization responsible for the data // ORIGIN / organization responsible for the data
CMNT("organization responsible for the data"); CMNT("organization responsible for the data");
FTKEY(TSTRING, "ORIGIN", "SAO RAS"); FTKEY(TSTRING, "ORIGIN", "SAO RAS");
// OBSERVAT / Observatory name // OBSERVAT / Observatory name
CMNT("Observatory name"); CMNT("Observatory name");
FTKEY(TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia"); FTKEY(TSTRING, "OBSERVAT", "Special Astrophysical Observatory, Russia");
// placement // placement
CMNT("Observatory altitude, m"); CMNT("Observatory altitude, m");
dtmp = TELALT; FTKEY(TDOUBLE, "ALT_OBS", &dtmp); dtmp = TELALT; FTKEY(TDOUBLE, "ALT_OBS", &dtmp);
CMNT("Observatory longitude, degr"); CMNT("Observatory longitude, degr");
dtmp = TELLONG; FTKEY(TDOUBLE, "LONG_OBS", &dtmp); dtmp = TELLONG; FTKEY(TDOUBLE, "LONG_OBS", &dtmp);
CMNT("Observatory lattitude, degr"); CMNT("Observatory lattitude, degr");
dtmp = TELLAT; FTKEY(TDOUBLE, "LAT_OBS", &dtmp); dtmp = TELLAT; FTKEY(TDOUBLE, "LAT_OBS", &dtmp);
/* /*
* Times * Times
*/ */
dtmp = S_time-EE_time; dtmp = S_time-EE_time;
// ST / sidereal time (hh:mm:ss.ms) // ST / sidereal time (hh:mm:ss.ms)
CMNT("Sidereal time: %s", time_asc(dtmp)); CMNT("Sidereal time: %s", time_asc(dtmp));
FTKEY(TDOUBLE, "ST", &dtmp); FTKEY(TDOUBLE, "ST", &dtmp);
// UT / universal time (hh:mm:ss.ms) // UT / universal time (hh:mm:ss.ms)
CMNT("Universal time: %s", time_asc(M_time)); CMNT("Universal time: %s", time_asc(M_time));
FTKEY(TDOUBLE, "UT", &M_time); FTKEY(TDOUBLE, "UT", &M_time);
CMNT("Julian date"); CMNT("Julian date");
FTKEY(TDOUBLE, "JD", &JDate); FTKEY(TDOUBLE, "JD", &JDate);
/* /*
* Telescope parameters * Telescope parameters
*/ */
switch(Tel_Focus){ switch(Tel_Focus){
case Nasmyth1 : val = "Nasmyth1"; break; case Nasmyth1 : val = "Nasmyth1"; break;
case Nasmyth2 : val = "Nasmyth2"; break; case Nasmyth2 : val = "Nasmyth2"; break;
default : val = "Prime"; break; default : val = "Prime"; break;
} }
// FOCUS / Focus of telescope (mm) // FOCUS / Focus of telescope (mm)
CMNT("Observation focus"); CMNT("Observation focus");
FTKEY(TSTRING, "FOCUS", val); FTKEY(TSTRING, "FOCUS", val);
// VAL_F / focus value // VAL_F / focus value
CMNT("Focus value (mm)"); CMNT("Focus value (mm)");
FTKEY(TDOUBLE, "VAL_F", &val_F); FTKEY(TDOUBLE, "VAL_F", &val_F);
// EQUINOX / Epoch of RA & DEC // EQUINOX / Epoch of RA & DEC
dtmp = 1900 + tm_ut->tm_year + tm_ut->tm_yday / 365.2422; dtmp = 1900 + tm_ut->tm_year + tm_ut->tm_yday / 365.2422;
CMNT("Epoch of RA & DEC"); CMNT("Epoch of RA & DEC");
FTKEY(TDOUBLE, "EQUINOX", &dtmp); FTKEY(TDOUBLE, "EQUINOX", &dtmp);
CMNT("Current object R.A.: %s", time_asc(CurAlpha)); CMNT("Current object R.A.: %s", time_asc(CurAlpha));
// RA / Right ascention (H.H) // RA / Right ascention (H.H)
dtmp = CurAlpha / 3600.; FTKEY(TDOUBLE, "RA", &dtmp); dtmp = CurAlpha / 3600.; FTKEY(TDOUBLE, "RA", &dtmp);
// DEC / Declination (D.D) // DEC / Declination (D.D)
CMNT("Current object Decl.: %s", angle_asc(CurDelta)); CMNT("Current object Decl.: %s", angle_asc(CurDelta));
dtmp = CurDelta / 3600.; FTKEY(TDOUBLE, "DEC", &dtmp); dtmp = CurDelta / 3600.; FTKEY(TDOUBLE, "DEC", &dtmp);
CMNT("Source R.A.: %s", time_asc(SrcAlpha)); CMNT("Source R.A.: %s", time_asc(SrcAlpha));
dtmp = SrcAlpha / 3600.; FTKEY(TDOUBLE, "S_RA", &dtmp); dtmp = SrcAlpha / 3600.; FTKEY(TDOUBLE, "S_RA", &dtmp);
CMNT("Source Decl.: %s", angle_asc(SrcDelta)); CMNT("Source Decl.: %s", angle_asc(SrcDelta));
dtmp = SrcDelta / 3600.; FTKEY(TDOUBLE, "S_DEC", &dtmp); dtmp = SrcDelta / 3600.; FTKEY(TDOUBLE, "S_DEC", &dtmp);
CMNT("Telescope R.A: %s", time_asc(val_Alp)); CMNT("Telescope R.A: %s", time_asc(val_Alp));
dtmp = val_Alp / 3600.; FTKEY(TDOUBLE, "T_RA", &dtmp); dtmp = val_Alp / 3600.; FTKEY(TDOUBLE, "T_RA", &dtmp);
CMNT("Telescope Decl.: %s", angle_asc(val_Del)); CMNT("Telescope Decl.: %s", angle_asc(val_Del));
dtmp = val_Del / 3600.; FTKEY(TDOUBLE, "T_DEC", &dtmp); dtmp = val_Del / 3600.; FTKEY(TDOUBLE, "T_DEC", &dtmp);
double a2000, d2000; double a2000, d2000;
calc_mean(InpAlpha, InpDelta, &a2000, &d2000); calc_mean(InpAlpha, InpDelta, &a2000, &d2000);
CMNT("R.A. given by user (for J2000): %s", time_asc(a2000)); CMNT("R.A. given by user (for J2000): %s", time_asc(a2000));
dtmp = a2000 / 3600.; dtmp = a2000 / 3600.;
FTKEY(TDOUBLE, "INPRA0", &dtmp); FTKEY(TDOUBLE, "INPRA0", &dtmp);
CMNT("Decl. given by user (for J2000): %s", angle_asc(d2000)); CMNT("Decl. given by user (for J2000): %s", angle_asc(d2000));
dtmp = d2000 / 3600; dtmp = d2000 / 3600;
FTKEY(TDOUBLE, "INPDEC0", &dtmp); FTKEY(TDOUBLE, "INPDEC0", &dtmp);
calc_mean(CurAlpha, CurDelta, &a2000, &d2000); calc_mean(CurAlpha, CurDelta, &a2000, &d2000);
CMNT("Current R.A. (for J2000): %s", time_asc(a2000)); CMNT("Current R.A. (for J2000): %s", time_asc(a2000));
dtmp = a2000 / 3600.; dtmp = a2000 / 3600.;
FTKEY(TDOUBLE, "CURRA0", &dtmp); FTKEY(TDOUBLE, "CURRA0", &dtmp);
CMNT("Current Decl. (for J2000): %s", angle_asc(d2000)); CMNT("Current Decl. (for J2000): %s", angle_asc(d2000));
dtmp = d2000 / 3600; dtmp = d2000 / 3600;
FTKEY(TDOUBLE, "CURDEC0", &dtmp); FTKEY(TDOUBLE, "CURDEC0", &dtmp);
// A / Azimuth // A / Azimuth
CMNT("Current object Azimuth: %s", angle_asc(tag_A)); CMNT("Current object Azimuth: %s", angle_asc(tag_A));
dtmp = tag_A / 3600.; FTKEY(TDOUBLE, "A", &dtmp); dtmp = tag_A / 3600.; FTKEY(TDOUBLE, "A", &dtmp);
// Z / Zenith distance // Z / Zenith distance
CMNT("Current object Zenith: %s", angle_asc(tag_Z)); CMNT("Current object Zenith: %s", angle_asc(tag_Z));
dtmp = tag_Z / 3600.; FTKEY(TDOUBLE, "Z", &dtmp); dtmp = tag_Z / 3600.; FTKEY(TDOUBLE, "Z", &dtmp);
// PARANGLE / Parallactic angle // PARANGLE / Parallactic angle
CMNT("Parallactic angle: %s", angle_asc(tag_P)); CMNT("Parallactic angle: %s", angle_asc(tag_P));
dtmp = tag_P / 3600.;FTKEY(TDOUBLE, "PARANGLE", &dtmp); dtmp = tag_P / 3600.;FTKEY(TDOUBLE, "PARANGLE", &dtmp);
CMNT("Telescope A: %s", angle_asc(val_A)); CMNT("Telescope A: %s", angle_asc(val_A));
dtmp = val_A / 3600.; FTKEY(TDOUBLE, "VAL_A", &dtmp); dtmp = val_A / 3600.; FTKEY(TDOUBLE, "VAL_A", &dtmp);
CMNT("Telescope Z: %s", angle_asc(val_Z)); CMNT("Telescope Z: %s", angle_asc(val_Z));
dtmp = val_Z / 3600.; FTKEY(TDOUBLE, "VAL_Z", &dtmp); dtmp = val_Z / 3600.; FTKEY(TDOUBLE, "VAL_Z", &dtmp);
CMNT("Current P2 value: %s", angle_asc(val_P)); CMNT("Current P2 value: %s", angle_asc(val_P));
dtmp = val_P / 3600.; FTKEY(TDOUBLE, "VAL_P", &dtmp); dtmp = val_P / 3600.; FTKEY(TDOUBLE, "VAL_P", &dtmp);
CMNT("Dome A: %s", angle_asc(val_D)); CMNT("Dome A: %s", angle_asc(val_D));
dtmp = val_D / 3600.; FTKEY(TDOUBLE, "VAL_D", &dtmp); dtmp = val_D / 3600.; FTKEY(TDOUBLE, "VAL_D", &dtmp);
// OUTTEMP / Out temperature (C) // OUTTEMP / Out temperature (C)
CMNT("Outern temperature, degC"); CMNT("Outern temperature, degC");
FTKEY(TDOUBLE, "OUTTEMP", &val_T1); FTKEY(TDOUBLE, "OUTTEMP", &val_T1);
// DOMETEMP / Dome temperature (C) // DOMETEMP / Dome temperature (C)
CMNT("In-dome temperature, degC"); CMNT("In-dome temperature, degC");
FTKEY(TDOUBLE, "DOMETEMP", &val_T2); FTKEY(TDOUBLE, "DOMETEMP", &val_T2);
// MIRRTEMP / Mirror temperature (C) // MIRRTEMP / Mirror temperature (C)
CMNT("Mirror temperature, degC"); CMNT("Mirror temperature, degC");
FTKEY(TDOUBLE, "MIRRTEMP", &val_T3); FTKEY(TDOUBLE, "MIRRTEMP", &val_T3);
// PRESSURE / Pressure (mmHg) // PRESSURE / Pressure (mmHg)
CMNT("Pressure, mmHg"); CMNT("Pressure, mmHg");
FTKEY(TDOUBLE, "PRESSURE", &val_B); FTKEY(TDOUBLE, "PRESSURE", &val_B);
// WIND / Wind speed (m/s) // WIND / Wind speed (m/s)
CMNT("Wind speed, m/s"); CMNT("Wind speed, m/s");
FTKEY(TDOUBLE, "WIND", &val_Wnd); FTKEY(TDOUBLE, "WIND", &val_Wnd);
CMNT("Humidity, %%"); CMNT("Humidity, %%");
FTKEY(TDOUBLE, "HUM", &val_Hmd); FTKEY(TDOUBLE, "HUM", &val_Hmd);
/* /*
* Airmass calculation * Airmass calculation
* by Reed D. Meyer * by Reed D. Meyer
*/ */
double am, acd, wcd, wam; double am, acd, wcd, wam;
dtmp = tm_loc->tm_yday; // current day of year dtmp = tm_loc->tm_yday; // current day of year
calc_airmass(dtmp, val_Hmd, val_B, val_T1+273.15, val_Z/3600., &am, &acd, &wcd, &wam); calc_airmass(dtmp, val_Hmd, val_B, val_T1+273.15, val_Z/3600., &am, &acd, &wcd, &wam);
//printf("am=%g, acd=%g, wcd=%g, wam=%g\n", am,acd,wcd,wam); //printf("am=%g, acd=%g, wcd=%g, wam=%g\n", am,acd,wcd,wam);
CMNT("Air mass by Reed D. Meyer"); CMNT("Air mass by Reed D. Meyer");
FTKEY(TDOUBLE, "AIRMASS", &am); FTKEY(TDOUBLE, "AIRMASS", &am);
CMNT("Water vapour air mass by Reed D. Meyer"); CMNT("Water vapour air mass by Reed D. Meyer");
FTKEY(TDOUBLE, "WVAM", &wam); FTKEY(TDOUBLE, "WVAM", &wam);
CMNT("Atm. column density by Reed D. Meyer, g/cm^2"); CMNT("Atm. column density by Reed D. Meyer, g/cm^2");
FTKEY(TDOUBLE, "ATMDENS", &acd); FTKEY(TDOUBLE, "ATMDENS", &acd);
CMNT("WV column density by Reed D. Meyer, g/cm^2"); CMNT("WV column density by Reed D. Meyer, g/cm^2");
FTKEY(TDOUBLE, "WVDENS", &wcd); FTKEY(TDOUBLE, "WVDENS", &wcd);
// if bta_queue nonempty write its data to HISTORY section // if bta_queue nonempty write its data to HISTORY section
if(bta_queue) write_bta_queue(fp); if(bta_queue) write_bta_queue(fp);
} }
// get parameters // get parameters
int get_params(BTA_PARAMS *P){ int get_params(BTA_PARAMS *P){
if(!shm_ready){ if(!shm_ready){
if(!get_shm_block(&sdat, ClientSide)) return -1; if(!get_shm_block(&sdat, ClientSide)) return -1;
else shm_ready = TRUE; else shm_ready = TRUE;
} }
if(!check_shm_block(&sdat)) return -1; if(!check_shm_block(&sdat)) return -1;
P->JD = JDate; P->JD = JDate;
P->Azimuth = val_A; P->Azimuth = val_A;
P->Zenith = val_Z; P->Zenith = val_Z;
P->P2 = val_P; P->P2 = val_P;
P->Wind = val_Wnd; P->Wind = val_Wnd;
return 0; return 0;
} }
int push_param(){ int push_param(){
DBG("Try to push parameter"); DBG("Try to push parameter");
if(!shm_ready){ if(!shm_ready){
if(!get_shm_block(&sdat, ClientSide)) return -4; if(!get_shm_block(&sdat, ClientSide)) return -4;
else shm_ready = TRUE; else shm_ready = TRUE;
} }
if(!check_shm_block(&sdat)) return -3; if(!check_shm_block(&sdat)) return -3;
BTA_PARAMS *Par = calloc(1, sizeof(BTA_PARAMS)); BTA_PARAMS *Par = calloc(1, sizeof(BTA_PARAMS));
BTA_Queue *qcur = calloc(1, sizeof(BTA_Queue)); BTA_Queue *qcur = calloc(1, sizeof(BTA_Queue));
if(!Par || !qcur){ if(!Par || !qcur){
free(Par); free(Par);
free(qcur); free(qcur);
return -2; // malloc error return -2; // malloc error
} }
if(get_params(Par)){ if(get_params(Par)){
free(Par); free(Par);
free(qcur); free(qcur);
return -1; // error getting parameters return -1; // error getting parameters
} }
qcur->data = Par; qcur->data = Par;
qcur->next = NULL; qcur->next = NULL;
qcur->last = qcur; qcur->last = qcur;
if(!bta_queue){ // initialisation of que if(!bta_queue){ // initialisation of que
bta_queue = qcur; bta_queue = qcur;
}else{ // variable que initialized previously }else{ // variable que initialized previously
bta_queue->last->next = qcur; bta_queue->last->next = qcur;
bta_queue->last = qcur; bta_queue->last = qcur;
} }
return 0; return 0;
} }
void write_bta_queue(fitsfile *fp){ void write_bta_queue(fitsfile *fp){
#define HISTRY(...) do{CMNT(__VA_ARGS__); WRITEHIST(fp);}while(0) #define HISTRY(...) do{CMNT(__VA_ARGS__); WRITEHIST(fp);}while(0)
if(!bta_queue || !fp) return; if(!bta_queue || !fp) return;
BTA_Queue *cur = bta_queue, *ptr; BTA_Queue *cur = bta_queue, *ptr;
BTA_PARAMS *P; BTA_PARAMS *P;
int i = 0; int i = 0;
do{ do{
P = cur->data; P = cur->data;
ptr = cur; ptr = cur;
HISTRY("Data record # %d", i); HISTRY("Data record # %d", i);
HISTRY("JD = %.8f / Julian date", P->JD); HISTRY("JD = %.8f / Julian date", P->JD);
HISTRY("T_AZ = %.8f / Telescope Az: %s", P->Azimuth / 3600., angle_asc(P->Azimuth)); HISTRY("T_AZ = %.8f / Telescope Az: %s", P->Azimuth / 3600., angle_asc(P->Azimuth));
HISTRY("T_ZD = %.8f / Telescope ZD: %s", P->Zenith / 3600., angle_asc(P->Zenith)); HISTRY("T_ZD = %.8f / Telescope ZD: %s", P->Zenith / 3600., angle_asc(P->Zenith));
HISTRY("T_P2 = %.8f / Current P: %s", P->P2 / 3600., angle_asc(P->P2)); HISTRY("T_P2 = %.8f / Current P: %s", P->P2 / 3600., angle_asc(P->P2));
HISTRY("WIND = %.2f / Wind speed, m/s", P->Wind); HISTRY("WIND = %.2f / Wind speed, m/s", P->Wind);
i++; i++;
cur = cur->next; cur = cur->next;
free(P); free(P);
free(ptr); free(ptr);
bta_queue = cur; bta_queue = cur;
}while(cur); }while(cur);
} }

View File

@ -23,6 +23,8 @@
#ifndef __BTA_PRINT_H__ #ifndef __BTA_PRINT_H__
#define __BTA_PRINT_H__ #define __BTA_PRINT_H__
#include <fitsio.h>
void write_bta_data(fitsfile *fp); void write_bta_data(fitsfile *fp);
int push_param(); int push_param();

345
bta_shdata.c Normal file
View File

@ -0,0 +1,345 @@
#include <crypt.h>
#include "bta_shdata.h"
#include "usefull_macros.h"
#pragma pack(push, 4)
// Main command channel (level 5)
struct CMD_Queue mcmd = {{"Mcmd"}, 0200,0,-1,0};
// Operator command channel (level 4)
struct CMD_Queue ocmd = {{"Ocmd"}, 0200,0,-1,0};
// User command channel (level 2/3)
struct CMD_Queue ucmd = {{"Ucmd"}, 0200,0,-1,0};
#define MSGLEN (80)
static char msg[MSGLEN];
#define PERR(...) do{snprintf(msg, MSGLEN, __VA_ARGS__); perror(msg);} while(0)
#ifndef BTA_MODULE
struct BTA_Data *sdt;
struct BTA_Local *sdtl;
struct SHM_Block sdat = {
{"Sdat"},
sizeof(struct BTA_Data),
2048,0444,
SHM_RDONLY,
bta_data_init,
bta_data_check,
bta_data_close,
ClientSide,-1,NULL
};
int snd_id = -1; // client sender ID
int cmd_src_pid = 0; // next command source PID
uint32_t cmd_src_ip = 0;// next command source IP
/**
* Init data
*/
void bta_data_init() {
sdt = (struct BTA_Data *)sdat.addr;
sdtl = (struct BTA_Local *)(sdat.addr+sizeof(struct BTA_Data));
if(sdat.side == ClientSide) {
if(sdt->magic != sdat.key.code) {
WARN("Wrong shared data (maybe server turned off)");
}
if(sdt->version == 0) {
WARN("Null shared data version (maybe server turned off)");
}
else if(sdt->version != BTA_Data_Ver) {
WARN("Wrong shared data version: I'am - %d, but server - %d ...",
BTA_Data_Ver, sdt->version );
}
if(sdt->size != sdat.size) {
if(sdt->size > sdat.size) {
WARN("Wrong shared area size: I needs - %d, but server - %d ...",
sdat.size, sdt->size );
} else {
WARN("Attention! Too little shared data structure!");
WARN("I needs - %d, but server gives only %d ...",
sdat.size, sdt->size );
WARN("May be server's version too old!?");
}
}
return;
}
/* ServerSide */
if(sdt->magic == sdat.key.code &&
sdt->version == BTA_Data_Ver &&
sdt->size == sdat.size)
return;
memset(sdat.addr, 0, sdat.maxsize);
sdt->magic = sdat.key.code;
sdt->version = BTA_Data_Ver;
sdt->size = sdat.size;
Tel_Hardware = Hard_On;
Pos_Corr = PC_On;
TrkOk_Mode = UseDiffVel | UseDiffAZ ;
inp_B = 591.;
Pressure = 595.;
PEP_code_A = 0x002aaa;
PEP_code_Z = 0x002aaa;
PEP_code_P = 0x002aaa;
PEP_code_F = 0x002aaa;
PEP_code_D = 0x002aaa;
DomeSEW_N = 1;
}
int bta_data_check() {
return( (sdt->magic == sdat.key.code) && (sdt->version == BTA_Data_Ver) );
}
void bta_data_close() {
if(sdat.side == ServerSide) {
sdt->magic = 0;
sdt->version = 0;
}
}
/**
* Allocate shared memory segment
*/
int get_shm_block(struct SHM_Block *sb, int server) {
int getsize = (server)? sb->maxsize : sb->size;
// first try to find existing one
sb->id = shmget(sb->key.code, getsize, sb->mode);
if(sb->id < 0 && errno == ENOENT && server){
// if no - try to create a new one
int cresize = sb->maxsize;
if(sb->size > cresize){
WARN("Wrong shm maxsize(%d) < realsize(%d)",sb->maxsize,sb->size);
cresize = sb->size;
}
sb->id = shmget(sb->key.code, cresize, IPC_CREAT|IPC_EXCL|sb->mode);
}
if(sb->id < 0){
if(server)
PERR("Can't create shared memory segment '%s'",sb->key.name);
else
PERR("Can't find shared segment '%s' (maybe no server process) ",sb->key.name);
return 0;
}
// attach it to our memory space
sb->addr = (unsigned char *) shmat(sb->id, NULL, sb->atflag);
if((long)sb->addr == -1){
PERR("Can't attach shared memory segment '%s'",sb->key.name);
return 0;
}
if(server && (shmctl(sb->id, SHM_LOCK, NULL) < 0)){
PERR("Can't prevents swapping of shared memory segment '%s'",sb->key.name);
return 0;
}
DBG("Create & attach shared memory segment '%s' %dbytes", sb->key.name, sb->size);
sb->side = server;
if(sb->init != NULL)
sb->init();
return 1;
}
int close_shm_block(struct SHM_Block *sb){
int ret;
if(sb->close != NULL)
sb->close();
if(sb->side == ServerSide) {
// ret = shmctl(sb->id, SHM_UNLOCK, NULL);
ret = shmctl(sb->id, IPC_RMID, NULL);
}
ret = shmdt (sb->addr);
return(ret);
}
/**
* Create|Find command queue
*/
void get_cmd_queue(struct CMD_Queue *cq, int server){
if (!server && cq->id >= 0) { //if already in use set current
snd_id = cq->id;
return;
}
// first try to find existing one
cq->id = msgget(cq->key.code, cq->mode);
// if no - try to create a new one
if(cq->id<0 && errno == ENOENT && server)
cq->id = msgget(cq->key.code, IPC_CREAT|IPC_EXCL|cq->mode);
if(cq->id<0){
if(server)
PERR("Can't create comand queue '%s'",cq->key.name);
else
PERR("Can't find comand queue '%s' (maybe no server process) ",cq->key.name);
return;
}
cq->side = server;
if(server){
char buf[120];
while(msgrcv(cq->id, (struct msgbuf *)buf, 112, 0, IPC_NOWAIT) > 0);
}else
snd_id = cq->id;
cq->acckey = 0;
}
#endif // BTA_MODULE
int check_shm_block(struct SHM_Block *sb) {
if(sb->check)
return(sb->check());
else return(0);
}
/**
* Set access key in current channel
*/
void set_acckey(uint32_t newkey){
if(snd_id < 0) return;
if(ucmd.id == snd_id) ucmd.acckey = newkey;
else if(ocmd.id == snd_id) ocmd.acckey = newkey;
else if(mcmd.id == snd_id) mcmd.acckey = newkey;
}
/**
* Setup source data for one following command if default values
* (IP == 0 - local, PID = current) not suits
*/
void set_cmd_src(uint32_t ip, int pid) {
cmd_src_pid = pid;
cmd_src_ip = ip;
}
#pragma pack(push, 4)
/**
* Send client commands to server
*/
void send_cmd(int cmd_code, char *buf, int size) {
struct my_msgbuf mbuf;
if(snd_id < 0) return;
if(size > 100) size = 100;
if(cmd_code > 0)
mbuf.mtype = cmd_code;
else
return;
if(ucmd.id == snd_id) mbuf.acckey = ucmd.acckey;
else if(ocmd.id == snd_id) mbuf.acckey = ocmd.acckey;
else if(mcmd.id == snd_id) mbuf.acckey = mcmd.acckey;
mbuf.src_pid = cmd_src_pid ? cmd_src_pid : getpid();
mbuf.src_ip = cmd_src_ip;
cmd_src_pid = cmd_src_ip = 0;
if(size > 0)
memcpy(mbuf.mtext, buf, size);
else {
mbuf.mtext[0] = 0;
size = 1;
}
msgsnd(snd_id, (struct msgbuf *)&mbuf, size+12, IPC_NOWAIT);
}
void send_cmd_noarg(int cmd_code) {
send_cmd(cmd_code, NULL, 0);
}
void send_cmd_str(int cmd_code, char *arg) {
send_cmd(cmd_code, arg, strlen(arg)+1);
}
void send_cmd_i1(int cmd_code, int32_t arg1) {
send_cmd(cmd_code, (char *)&arg1, sizeof(int32_t));
}
void send_cmd_i2(int cmd_code, int32_t arg1, int32_t arg2) {
int32_t ibuf[2];
ibuf[0] = arg1;
ibuf[1] = arg2;
send_cmd(cmd_code, (char *)ibuf, 2*sizeof(int32_t));
}
void send_cmd_i3(int cmd_code, int32_t arg1, int32_t arg2, int32_t arg3) {
int32_t ibuf[3];
ibuf[0] = arg1;
ibuf[1] = arg2;
ibuf[2] = arg3;
send_cmd(cmd_code, (char *)ibuf, 3*sizeof(int32_t));
}
void send_cmd_i4(int cmd_code, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) {
int32_t ibuf[4];
ibuf[0] = arg1;
ibuf[1] = arg2;
ibuf[2] = arg3;
ibuf[3] = arg4;
send_cmd(cmd_code, (char *)ibuf, 4*sizeof(int32_t));
}
void send_cmd_d1(int32_t cmd_code, double arg1) {
send_cmd(cmd_code, (char *)&arg1, sizeof(double));
}
void send_cmd_d2(int cmd_code, double arg1, double arg2) {
double dbuf[2];
dbuf[0] = arg1;
dbuf[1] = arg2;
send_cmd(cmd_code, (char *)dbuf, 2*sizeof(double));
}
void send_cmd_i1d1(int cmd_code, int32_t arg1, double arg2) {
struct {
int32_t ival;
double dval;
} buf;
buf.ival = arg1;
buf.dval = arg2;
send_cmd(cmd_code, (char *)&buf, sizeof(buf));
}
void send_cmd_i2d1(int cmd_code, int32_t arg1, int32_t arg2, double arg3) {
struct {
int32_t ival[2];
double dval;
} buf;
buf.ival[0] = arg1;
buf.ival[1] = arg2;
buf.dval = arg3;
send_cmd(cmd_code, (char *)&buf, sizeof(buf));
}
void send_cmd_i3d1(int cmd_code, int32_t arg1, int32_t arg2, int32_t arg3, double arg4) {
struct {
int32_t ival[3];
double dval;
} buf;
buf.ival[0] = arg1;
buf.ival[1] = arg2;
buf.ival[2] = arg3;
buf.dval = arg4;
send_cmd(cmd_code, (char *)&buf, sizeof(buf));
}
void encode_lev_passwd(char *passwd, int nlev, uint32_t *keylev, uint32_t *codlev){
char salt[4];
char *encr;
union {
uint32_t ui;
char c[4];
} key, cod;
sprintf(salt,"L%1d",nlev);
encr = (char *)crypt(passwd, salt);
cod.c[0] = encr[2];
key.c[0] = encr[3];
cod.c[1] = encr[4];
key.c[1] = encr[5];
cod.c[2] = encr[6];
key.c[2] = encr[7];
cod.c[3] = encr[8];
key.c[3] = encr[9];
*keylev = key.ui;
*codlev = cod.ui;
}
int find_lev_passwd(char *passwd, uint32_t *keylev, uint32_t *codlev){
int nlev;
for(nlev = 5; nlev > 0; --nlev){
encode_lev_passwd(passwd, nlev, keylev, codlev);
if(*codlev == code_Lev(nlev)) break;
}
return(nlev);
}
int check_lev_passwd(char *passwd){
uint32_t keylev,codlev;
int nlev;
nlev = find_lev_passwd(passwd, &keylev, &codlev);
if(nlev > 0) set_acckey(keylev);
return(nlev);
}
#pragma pack(pop)

File diff suppressed because it is too large Load Diff

View File

@ -37,114 +37,114 @@ double avr, std; // average value and standard deviation
* if user set option fan-speed=F, then speed would be set to F * if user set option fan-speed=F, then speed would be set to F
* if onoff == FALSE, try to set speed according to hot Peltier temperature * if onoff == FALSE, try to set speed according to hot Peltier temperature
* if onoff == TRUE, set speed=3, if cooler is on, else set speed=0 * if onoff == TRUE, set speed=3, if cooler is on, else set speed=0
*/ *
void AutoadjustFanSpeed(bool onoff){ void AutoadjustFanSpeed(bool onoff){
int Mode = 3, curMode, stat; int Mode = 3, curMode, stat;
double temp, HotTemp; double temp, HotTemp;
stat = ApnGlueGetTemp(&temp); stat = ApnGlueGetTemp(&temp);
curMode = ApnGlueGetFan(); curMode = ApnGlueGetFan();
HotTemp = ApnGlueGetHotTemp(); HotTemp = ApnGlueGetHotTemp();
if(fanspd != -1){ if(fanspd != -1){
ApnGlueSetFan(fanspd); ApnGlueSetFan(fanspd);
} }
if(HotTemp < -30.){ // -255. - there's no thermometer on hot side if(HotTemp < -30.){ // -255. - there's no thermometer on hot side
// "÷ ×ÁÛÅÍ Ó×ÅÔÏÐÒÉÅÍÎÉËÅ ÎÅÔ \"ÇÏÒÑÞÅÇÏ\" ÔÅÒÍÏÍÅÔÒÁ" // "÷ ×ÁÛÅÍ Ó×ÅÔÏÐÒÉÅÍÎÉËÅ ÎÅÔ \"ÇÏÒÑÞÅÇÏ\" ÔÅÒÍÏÍÅÔÒÁ"
info(_("Your camera have no hot temperature sensor\n")); info(_("Your camera have no hot temperature sensor\n"));
return; return;
} }
if(onoff){ // quit, set speed according cooler status if(onoff){ // quit, set speed according cooler status
if(!stat && HotTemp < 30.) Mode = 0; // cooler is off -> turn fans off if(!stat && HotTemp < 30.) Mode = 0; // cooler is off -> turn fans off
}else{ }else{
if(HotTemp < 20.) Mode = 0; if(HotTemp < 20.) Mode = 0;
else if(HotTemp < 25.) Mode = 1; else if(HotTemp < 25.) Mode = 1;
else if(HotTemp < 30.) Mode = 2; else if(HotTemp < 30.) Mode = 2;
} }
if(Mode == curMode) return; if(Mode == curMode) return;
ApnGlueSetFan(Mode); ApnGlueSetFan(Mode);
if(ApnGlueGetFan() == Mode) if(ApnGlueGetFan() == Mode)
// "õÓÔÁÎÁ×ÌÉ×ÁÀ ÓËÏÒÏÓÔØ ×ÒÁÝÅÎÉÑ ×ÅÎÔÉÌÑÔÏÒÏ× × %d\n" // "õÓÔÁÎÁ×ÌÉ×ÁÀ ÓËÏÒÏÓÔØ ×ÒÁÝÅÎÉÑ ×ÅÎÔÉÌÑÔÏÒÏ× × %d\n"
info(_("Set fan speed %d\n"), Mode); info(_("Set fan speed %d\n"), Mode);
else else
// "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÓËÏÒÏÓÔØ ×ÒÁÝÅÎÉÑ ×ÅÎÔÉÌÑÔÏÒÏ×!\n" // "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÓËÏÒÏÓÔØ ×ÒÁÝÅÎÉÑ ×ÅÎÔÉÌÑÔÏÒÏ×!\n"
ERR("Can't set fan speed\n"); ERR("Can't set fan speed\n");
} }*/
double printCoolerStat(double *t_ext){ double printCoolerStat(double *t_ext){
double temp, extemp, settemp; double temp, extemp, settemp;
char *s; char *s;
int stat = ApnGlueGetTemp(&temp); int stat = ApnGlueGetTemp(&temp);
extemp = ApnGlueGetHotTemp(); extemp = ApnGlueGetHotTemp();
if(ApnGlueReadSetPoint(&settemp, NULL)){ if(ApnGlueReadSetPoint(&settemp, NULL)){
// "ãÅÌÅ×ÁÑ ÔÅÍÐÅÒÁÔÕÒÁ: %g\n" // "ãÅÌÅ×ÁÑ ÔÅÍÐÅÒÁÔÕÒÁ: %g\n"
info(_("Cooler setpoint: %g\n"), settemp); info(_("Cooler setpoint: %g\n"), settemp);
} }
switch(stat){ switch(stat){
case 0: case 0:
// "èÏÌÏÄÉÌØÎÉË ÏÔËÌÀÞÅÎ" // "èÏÌÏÄÉÌØÎÉË ÏÔËÌÀÞÅÎ"
s = _("Cooler is off"); break; s = _("Cooler is off"); break;
case 1: case 1:
// "õÓÔÁÎÏ×ËÁ ÚÁÄÁÎÎÏÊ ÔÅÍÐÅÒÁÔÕÒÙ" // "õÓÔÁÎÏ×ËÁ ÚÁÄÁÎÎÏÊ ÔÅÍÐÅÒÁÔÕÒÙ"
s = _("Go to setpoint"); break; s = _("Go to setpoint"); break;
case 2: case 2:
// "ðÏÄÄÅÒÖÁÎÉÅ ÚÁÄÁÎÎÏÊ ÔÅÍÐÅÒÁÔÕÒÙ" // "ðÏÄÄÅÒÖÁÎÉÅ ÚÁÄÁÎÎÏÊ ÔÅÍÐÅÒÁÔÕÒÙ"
s = _("Keeping setpoint"); break; s = _("Keeping setpoint"); break;
default: default:
// "óÔÁÔÕÓ ÎÅÉÚ×ÅÓÔÅÎ" // "óÔÁÔÕÓ ÎÅÉÚ×ÅÓÔÅÎ"
s = _("Unknown status"); s = _("Unknown status");
} }
info("%s, T=%g, Thot=%g\n", s, temp, extemp); info("%s, T=%g, Thot=%g\n", s, temp, extemp);
if(t_ext) *t_ext = extemp; if(t_ext) *t_ext = extemp;
return temp; return temp;
} }
void print_stat(unsigned short *img, long size, FILE *f){ void print_stat(unsigned short *img, long size, FILE *f){
long i, Noverld = 0L, N = 0L; long i, Noverld = 0L, N = 0L;
double pv, sum=0., sum2=0., sz = (double)size, tres; double pv, sum=0., sum2=0., sz = (double)size, tres;
unsigned short *ptr = img, val, valoverld; unsigned short *ptr = img, val, valoverld;
max = 0; min = 65535; max = 0; min = 65535;
if(twelveBit) min = 4095; if(twelveBit) min = 4095;
valoverld = min - 5; valoverld = min - 5;
for(i = 0; i < size; i++, ptr++){ for(i = 0; i < size; i++, ptr++){
val = *ptr; val = *ptr;
pv = (double) val; pv = (double) val;
sum += pv; sum += pv;
sum2 += (pv * pv); sum2 += (pv * pv);
if(max < val) max = val; if(max < val) max = val;
if(min > val) min = val; if(min > val) min = val;
if(val >= valoverld) Noverld++; if(val >= valoverld) Noverld++;
} }
// "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n" // "óÔÁÔÉÓÔÉËÁ ÐÏ ÉÚÏÂÒÁÖÅÎÉÀ:\n"
printf(_("Image stat:\n")); printf(_("Image stat:\n"));
avr = sum/sz; avr = sum/sz;
printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr, printf("avr = %.1f, std = %.1f, Noverload = %ld\n", avr,
std = sqrt(fabs(sum2/sz - avr*avr)), Noverld); std = sqrt(fabs(sum2/sz - avr*avr)), Noverld);
printf("max = %u, min = %u, size = %ld\n", max, min, size); printf("max = %u, min = %u, size = %ld\n", max, min, size);
if(!f) return; if(!f) return;
// full statistics // full statistics
fprintf(f, "%d\t%d\t%.3f\t%.3f\t%ld\t", max, min, avr, std, Noverld); fprintf(f, "%d\t%d\t%.3f\t%.3f\t%ld\t", max, min, avr, std, Noverld);
Noverld = 0L; Noverld = 0L;
ptr = img; sum = 0.; sum2 = 0.; ptr = img; sum = 0.; sum2 = 0.;
tres = avr + 3. * std; // max treshold == 3sigma tres = avr + 3. * std; // max treshold == 3sigma
for(i = 0; i < size; i++, ptr++){ for(i = 0; i < size; i++, ptr++){
val = *ptr; val = *ptr;
pv = (double) val; pv = (double) val;
if(pv > tres){ if(pv > tres){
Noverld++; // now this is an amount of overload pixels Noverld++; // now this is an amount of overload pixels
continue; continue;
} }
sum += pv; sum += pv;
sum2 += (pv * pv); sum2 += (pv * pv);
N++; N++;
} }
if(N == 0L){ if(N == 0L){
fprintf(f, "err\n"); fprintf(f, "err\n");
return; return;
} }
sz = (double)N; sz = (double)N;
avr = sum/sz; std = sqrt(fabs(sum2/sz - avr*avr)); avr = sum/sz; std = sqrt(fabs(sum2/sz - avr*avr));
fprintf(f, "%ld\t%.3f\t%.3f\n", Noverld, avr, std); fprintf(f, "%ld\t%.3f\t%.3f\n", Noverld, avr, std);
fflush(f); fflush(f);
printf("Novr3 = %ld\n", Noverld); printf("Novr3 = %ld\n", Noverld);
} }
@ -162,171 +162,171 @@ void print_stat(unsigned short *img, long size, FILE *f){
int writefits(char *filename, int width, int height, void *data){ int writefits(char *filename, int width, int height, void *data){
long naxes[2] = {width, height};//, startTime; long naxes[2] = {width, height};//, startTime;
double tmp = 0.0; double tmp = 0.0;
unsigned short ustmp; unsigned short ustmp;
struct tm *tm_starttime; struct tm *tm_starttime;
char buf[80]; char buf[80];
time_t savetime = time(NULL); time_t savetime = time(NULL);
fitsfile *fp = NULL; fitsfile *fp = NULL;
TRYFITS(fits_create_file, &fp, filename); TRYFITS(fits_create_file, &fp, filename);
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes); TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
// FILE / Input file original name // FILE / Input file original name
WRITEKEY(TSTRING, "FILE", filename, "Input file original name"); WRITEKEY(TSTRING, "FILE", filename, "Input file original name");
/* /*
* Detector parameters * Detector parameters
*/ */
// DETECTOR / detector // DETECTOR / detector
if(camera){ if(camera){
WRITEKEY(TSTRING, "DETECTOR", camera, "Detector model"); WRITEKEY(TSTRING, "DETECTOR", camera, "Detector model");
} }
// SENSOR / sensor // SENSOR / sensor
if(sensor){ if(sensor){
WRITEKEY(TSTRING, "SENSOR", sensor, "Camera sensor model"); WRITEKEY(TSTRING, "SENSOR", sensor, "Camera sensor model");
} }
// INSTRUME / Instrument // INSTRUME / Instrument
if(instrument){ if(instrument){
WRITEKEY(TSTRING, "INSTRUME", instrument, "Instrument"); WRITEKEY(TSTRING, "INSTRUME", instrument, "Instrument");
}else }else
WRITEKEY(TSTRING, "INSTRUME", "direct imaging", "Instrument"); WRITEKEY(TSTRING, "INSTRUME", "direct imaging", "Instrument");
snprintf(buf, 79, "%.g x %.g", pixX, pixY); snprintf(buf, 79, "%.g x %.g", pixX, pixY);
// PXSIZE / pixel size // PXSIZE / pixel size
WRITEKEY(TSTRING, "PXSIZE", buf, "Pixel size in mkm"); WRITEKEY(TSTRING, "PXSIZE", buf, "Pixel size in mkm");
// XPIXELSZ, YPIXELSZ -- the same // XPIXELSZ, YPIXELSZ -- the same
WRITEKEY(TDOUBLE, "XPIXELSZ", &pixX, "X pixel size in mkm"); WRITEKEY(TDOUBLE, "XPIXELSZ", &pixX, "X pixel size in mkm");
WRITEKEY(TDOUBLE, "YPIXELSZ", &pixY, "Y pixel size in mkm"); WRITEKEY(TDOUBLE, "YPIXELSZ", &pixY, "Y pixel size in mkm");
WRITEKEY(TSTRING, "VIEWFLD", viewfield, "Camera field of view"); WRITEKEY(TSTRING, "VIEWFLD", viewfield, "Camera field of view");
if(exptime == 0) sprintf(buf, "bias"); if(exptime == 0) sprintf(buf, "bias");
else if(shutter == 0) sprintf(buf, "dark"); else if(shutter == 0) sprintf(buf, "dark");
else if(objtype) strncpy(buf, objtype, 79); else if(objtype) strncpy(buf, objtype, 79);
else sprintf(buf, "object"); else sprintf(buf, "object");
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push // IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type"); WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type");
// DATAMAX, DATAMIN / Max,min pixel value // DATAMAX, DATAMIN / Max,min pixel value
ustmp = ((twelveBit) ? 4095 : 65535); ustmp = ((twelveBit) ? 4095 : 65535);
WRITEKEY(TUSHORT, "DATAMAX", &ustmp, "Max pixel value"); WRITEKEY(TUSHORT, "DATAMAX", &ustmp, "Max pixel value");
ustmp = 0; ustmp = 0;
WRITEKEY(TUSHORT, "DATAMIN", &ustmp, "Min pixel value"); WRITEKEY(TUSHORT, "DATAMIN", &ustmp, "Min pixel value");
// Some Statistics // Some Statistics
WRITEKEY(TUSHORT, "STATMAX", &max, "Max data value"); WRITEKEY(TUSHORT, "STATMAX", &max, "Max data value");
WRITEKEY(TUSHORT, "STATMIN", &min, "Min data value"); WRITEKEY(TUSHORT, "STATMIN", &min, "Min data value");
WRITEKEY(TDOUBLE, "STATAVR", &avr, "Average data value"); WRITEKEY(TDOUBLE, "STATAVR", &avr, "Average data value");
WRITEKEY(TDOUBLE, "STATSTD", &std, "Standart deviation of data value"); WRITEKEY(TDOUBLE, "STATSTD", &std, "Standart deviation of data value");
// Temperatures // Temperatures
WRITEKEY(TDOUBLE, "TEMP0", &temperature, "Camera temperature at exp. start (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)"); WRITEKEY(TDOUBLE, "TEMP1", &t_int, "Camera temperature at exp. end (degr C)");
if(t_ext > -30.) // there's a hot temp sensor if(t_ext > -30.) // there's a hot temp sensor
WRITEKEY(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; tmp = (temperature + t_int) / 2. + 273.15;
// CAMTEMP / Camera temperature (K) // CAMTEMP / Camera temperature (K)
WRITEKEY(TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)"); WRITEKEY(TDOUBLE, "CAMTEMP", &tmp, "Camera temperature (K)");
tmp = (double)exptime / 1000.; tmp = (double)exptime / 1000.;
// EXPTIME / actual exposition time (sec) // EXPTIME / actual exposition time (sec)
WRITEKEY(TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)"); WRITEKEY(TDOUBLE, "EXPTIME", &tmp, "actual exposition time (sec)");
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC) // DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime)); strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
WRITEKEY(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); tm_starttime = localtime(&expStartsAt);
/* /*
* startTime = (long)expStartsAt; * startTime = (long)expStartsAt;
* strftime(buf, 79, "exposition starts at %d/%m/%Y, %H:%M:%S (local)", tm_starttime); * strftime(buf, 79, "exposition starts at %d/%m/%Y, %H:%M:%S (local)", tm_starttime);
* WRITEKEY(fp, TLONG, "UNIXTIME", &startTime, buf); * WRITEKEY(fp, TLONG, "UNIXTIME", &startTime, buf);
*/ */
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", tm_starttime); strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", tm_starttime);
// DATE-OBS / DATE OF OBS. // DATE-OBS / DATE OF OBS.
WRITEKEY(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) * // START / Measurement start time (local) (hh:mm:ss)
* strftime(buf, 79, "%H:%M:%S", tm_starttime); * strftime(buf, 79, "%H:%M:%S", tm_starttime);
* WRITEKEY(fp, TSTRING, "START", buf, "Measurement start time (hh:mm:ss, local)"); * WRITEKEY(fp, TSTRING, "START", buf, "Measurement start time (hh:mm:ss, local)");
*/ */
// OBJECT / Object name // OBJECT / Object name
if(objname){ if(objname){
WRITEKEY(TSTRING, "OBJECT", objname, "Object name"); WRITEKEY(TSTRING, "OBJECT", objname, "Object name");
} }
// BINNING / Binning // BINNING / Binning
if(hbin != 1 || vbin != 1){ if(hbin != 1 || vbin != 1){
snprintf(buf, 79, "%d x %d", hbin, vbin); snprintf(buf, 79, "%d x %d", hbin, vbin);
WRITEKEY(TSTRING, "BINNING", buf, "Binning (hbin x vbin)"); WRITEKEY(TSTRING, "BINNING", buf, "Binning (hbin x vbin)");
} }
WRITEKEY(TINT, "XBIN", &hbin, "Horizontal binning"); WRITEKEY(TINT, "XBIN", &hbin, "Horizontal binning");
WRITEKEY(TINT, "YBIN", &vbin, "Vertical binning"); WRITEKEY(TINT, "YBIN", &vbin, "Vertical binning");
// OBSERVER / Observers // OBSERVER / Observers
if(observers){ if(observers){
WRITEKEY(TSTRING, "OBSERVER", observers, "Observers"); WRITEKEY(TSTRING, "OBSERVER", observers, "Observers");
} }
// PROG-ID / Observation program identifier // PROG-ID / Observation program identifier
if(prog_id){ if(prog_id){
WRITEKEY(TSTRING, "PROG-ID", prog_id, "Observation program identifier"); WRITEKEY(TSTRING, "PROG-ID", prog_id, "Observation program identifier");
} }
// AUTHOR / Author of the program // AUTHOR / Author of the program
if(author){ if(author){
WRITEKEY(TSTRING, "AUTHOR", author, "Author of the program"); WRITEKEY(TSTRING, "AUTHOR", author, "Author of the program");
} }
#ifdef USE_BTA #ifdef USE_BTA
write_bta_data(fp); write_bta_data(fp);
#endif #endif
check_wcs(); check_wcs();
write_list(fp); write_list(fp);
TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data); TRYFITS(fits_write_img, fp, TUSHORT, 1, width * height, data);
TRYFITS(fits_close_file, fp); TRYFITS(fits_close_file, fp);
return 0; return 0;
} }
#ifdef USEPNG #ifdef USEPNG
int writepng(char *filename, int width, int height, void *data){ int writepng(char *filename, int width, int height, void *data){
int err; int err;
FILE *fp = NULL; FILE *fp = NULL;
png_structp pngptr = NULL; png_structp pngptr = NULL;
png_infop infoptr = NULL; png_infop infoptr = NULL;
void *row; png_const_bytep row = data + (height-1)*width*sizeof(u_int16_t);
if ((fp = fopen(filename, "wb")) == NULL){ if ((fp = fopen(filename, "wb")) == NULL){
err = -errno; err = -errno;
goto done; goto done;
} }
if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL)) == NULL){ NULL, NULL, NULL)) == NULL){
err = -ENOMEM; err = -ENOMEM;
goto done; goto done;
} }
if ((infoptr = png_create_info_struct(pngptr)) == NULL){ if ((infoptr = png_create_info_struct(pngptr)) == NULL){
err = -ENOMEM; err = -ENOMEM;
goto done; goto done;
} }
png_init_io(pngptr, fp); png_init_io(pngptr, fp);
png_set_compression_level(pngptr, 6); png_set_compression_level(pngptr, 5);
png_set_IHDR(pngptr, infoptr, width, height, 16, PNG_COLOR_TYPE_GRAY, png_set_IHDR(pngptr, infoptr, width, height, 16, PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
PNG_FILTER_TYPE_DEFAULT); PNG_FILTER_TYPE_DEFAULT);
png_write_info(pngptr, infoptr); png_write_info(pngptr, infoptr);
png_set_swap(pngptr); png_set_swap(pngptr);
for(row = data; height > 0; row += width * sizeof(u_int16_t), height--) for(; height > 0; row -= width * sizeof(u_int16_t), height--)
png_write_row(pngptr, row); png_write_row(pngptr, row);
png_write_end(pngptr, infoptr); png_write_end(pngptr, infoptr);
err = 0; err = 0;
done: done:
if(fp) fclose(fp); if(fp) fclose(fp);
if(pngptr) png_destroy_write_struct(&pngptr, &infoptr); if(pngptr) png_destroy_write_struct(&pngptr, &infoptr);
return err; return err;
} }
#endif /* USEPNG */ #endif /* USEPNG */
#ifdef USERAW #ifdef USERAW
int writeraw(char *filename, int width, int height, void *data){ int writeraw(char *filename, int width, int height, void *data){
int fd, size, err; int fd, size, err;
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) == -1){ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) == -1){
warn("open(%s) failed", filename); warn("open(%s) failed", filename);
return -errno; return -errno;
} }
size = width * height * sizeof(unsigned short); size = width * height * sizeof(unsigned short);
if ((err = write(fd, data, size)) != size){ if ((err = write(fd, data, size)) != size){
warn("write() failed"); warn("write() failed");
err = -errno; err = -errno;
} }
else err = 0; else err = 0;
close(fd); close(fd);
return err; return err;
} }
#endif // USERAW #endif // USERAW
@ -339,51 +339,51 @@ int writeraw(char *filename, int width, int height, void *data){
* @argument rgb - rgb array (GLubyte [3]) * @argument rgb - rgb array (GLubyte [3])
*/ */
void gray2rgb(double gray, GLubyte *rgb){ void gray2rgb(double gray, GLubyte *rgb){
int i = gray * 4.; int i = gray * 4.;
double x = (gray - (double)i * .25) * 4.; double x = (gray - (double)i * .25) * 4.;
GLubyte r = 0, g = 0, b = 0; GLubyte r = 0, g = 0, b = 0;
//r = g = b = (gray < 1) ? gray * 256 : 255; //r = g = b = (gray < 1) ? gray * 256 : 255;
switch(i){ switch(i){
case 0: case 0:
g = (GLubyte)(255. * x); g = (GLubyte)(255. * x);
b = 255; b = 255;
break; break;
case 1: case 1:
g = 255; g = 255;
b = (GLubyte)(255. * (1. - x)); b = (GLubyte)(255. * (1. - x));
break; break;
case 2: case 2:
r = (GLubyte)(255. * x); r = (GLubyte)(255. * x);
g = 255; g = 255;
break; break;
case 3: case 3:
r = 255; r = 255;
g = (GLubyte)(255. * (1. - x)); g = (GLubyte)(255. * (1. - x));
break; break;
default: default:
r = 255; r = 255;
} }
*rgb++ = r; *rgb++ = r;
*rgb++ = g; *rgb++ = g;
*rgb = b; *rgb = b;
} }
double linfun(double arg){ return arg; } // bung for PREVIEW_LINEAR static double linfun(double arg){ return arg; } // bung for PREVIEW_LINEAR
double logfun(double arg){ return log(1.+arg); } // for PREVIEW_LOG static double logfun(double arg){ return log(1.+arg); } // for PREVIEW_LOG
double (*colorfun)(double) = linfun; // default function to convert color static double (*colorfun)(double) = linfun; // default function to convert color
void change_colorfun(colorfn_type f){ void change_colorfun(colorfn_type f){
switch (f){ switch (f){
case COLORFN_LINEAR: case COLORFN_LINEAR:
colorfun = linfun; colorfun = linfun;
break; break;
case COLORFN_LOG: case COLORFN_LOG:
colorfun = logfun; colorfun = logfun;
break; break;
default: // sqrt default: // sqrt
colorfun = sqrt; colorfun = sqrt;
} }
} }
/** /**
@ -393,28 +393,28 @@ void change_colorfun(colorfn_type f){
* array dst should have size w*h*3 * array dst should have size w*h*3
*/ */
void convert_grayimage(unsigned short *src, GLubyte *dst, int w, int h){ void convert_grayimage(unsigned short *src, GLubyte *dst, int w, int h){
FNAME(); FNAME();
int x, y, S = w*h; int x, y, S = w*h;
unsigned short *ptr = src; unsigned short *ptr = src;
double avr, wd, max, min; double avr, wd, max, min;
avr = max = min = (double)*src; avr = max = min = (double)*src;
for(x = 1; x < S; x++, ptr++){ for(x = 1; x < S; x++, ptr++){
double pix = (double) *ptr; double pix = (double) *ptr;
if(pix > max) max = pix; if(pix > max) max = pix;
if(pix < min) min = pix; if(pix < min) min = pix;
avr += pix; avr += pix;
} }
avr /= (double)S; avr /= (double)S;
wd = max - min; wd = max - min;
if(wd > DBL_EPSILON) avr = (avr - min) / wd; // normal average by preview if(wd > DBL_EPSILON) avr = (avr - min) / wd; // normal average by preview
if(avr < 0.6) wd *= avr + 0.2; if(avr < 0.6) wd *= avr + 0.2;
if(wd < DBL_EPSILON) wd = 1.; if(wd < DBL_EPSILON) wd = 1.;
DBG("stat: sz=(%dx%d) avr=%g wd=%g max=%g min=%g", w,h,avr, wd, max, min); DBG("stat: sz=(%dx%d) avr=%g wd=%g max=%g min=%g", w,h,avr, wd, max, min);
for(y = 0; y < h; y++){ for(y = 0; y < h; y++){
for(x = 0; x < w; x++, dst += 3, src++){ for(x = 0; x < w; x++, dst += 3, src++){
gray2rgb(colorfun((*src - min) / wd), dst); gray2rgb(colorfun((*src - min) / wd), dst);
} }
} }
} }
#endif // IMAGEVIEW #endif // IMAGEVIEW

View File

@ -23,17 +23,20 @@
#ifndef __CAMTOOLS_H__ #ifndef __CAMTOOLS_H__
#define __CAMTOOLS_H__ #define __CAMTOOLS_H__
#include <fitsio.h>
#include <stdbool.h>
#define TRYFITS(f, ...) \ #define TRYFITS(f, ...) \
do{if(!test_headers){ int status = 0; \ do{if(!test_headers){ int status = 0; \
f(__VA_ARGS__, &status); \ f(__VA_ARGS__, &status); \
if (status){ \ if (status){ \
fits_report_error(stderr, status); \ fits_report_error(stderr, status); \
return -1;} \ return -1;} \
}}while(0) }}while(0)
#define WRITEKEY(...) do{add_fits_header(__VA_ARGS__);}while(0) #define WRITEKEY(...) do{add_fits_header(__VA_ARGS__);}while(0)
void print_fits_header(fitsfile *fptr, int datatype, char *keyname, void print_fits_header(fitsfile *fptr, int datatype, char *keyname,
void *value, char *comment); void *value, char *comment);
extern char *camera, *sensor, viewfield[]; extern char *camera, *sensor, viewfield[];
extern double pixX, pixY, t_ext, t_int; extern double pixX, pixY, t_ext, t_int;
@ -42,7 +45,7 @@ extern double avr, std;
extern time_t expStartsAt; extern time_t expStartsAt;
void AutoadjustFanSpeed(bool onoff); //void AutoadjustFanSpeed(bool onoff);
double printCoolerStat(double *t_ext); double printCoolerStat(double *t_ext);
void print_stat(unsigned short *img, long size, FILE* f); void print_stat(unsigned short *img, long size, FILE* f);
@ -57,16 +60,16 @@ int writeraw(char *filename, int width, int height, void *data);
#endif // USERAW #endif // USERAW
#ifdef IMAGEVIEW #ifdef IMAGEVIEW
#include <GL/glut.h>
#include <GL/glext.h>
#include <GL/freeglut.h> #include <GL/freeglut.h>
#include <GL/glext.h>
#include <GL/glut.h>
#include <math.h> #include <math.h>
// functions for converting grayscale value into colour // functions for converting grayscale value into colour
typedef enum{ typedef enum{
COLORFN_LINEAR, // linear COLORFN_LINEAR, // linear
COLORFN_LOG, // ln COLORFN_LOG, // ln
COLORFN_SQRT // sqrt COLORFN_SQRT // sqrt
} colorfn_type; } colorfn_type;
void change_colorfun(colorfn_type f); void change_colorfun(colorfn_type f);

653
defhdrs.c
View File

@ -32,17 +32,16 @@ YPIXELSZ
IMSCALE IMSCALE
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
#include <math.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <fitsio.h> #include <fitsio.h>
#include <math.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
#include "defhdrs.h"
#include "usage.h"
#include "macros.h"
#include "camtools.h" #include "camtools.h"
#include "defhdrs.h"
#include "macros.h"
#include "usage.h"
// global keylist // global keylist
static KeyList *FITS_keys = NULL; static KeyList *FITS_keys = NULL;
@ -50,30 +49,30 @@ double crval1 = -5e5, crval2 = -5e5, crpix1 = -5e5, crpix2 = -5e5;
double CD[2][2] = {{0.,0.}, {0.,0.}}; double CD[2][2] = {{0.,0.}, {0.,0.}};
void get_defhdrs(char *fname){ void get_defhdrs(char *fname){
mmapbuf *mmb = NULL; mmapbuf *mmb = NULL;
if(!fname){ // find in default file: ~/$DEFCONF if(!fname){ // find in default file: ~/$DEFCONF
const char *homedir; const char *homedir;
if ((homedir = getenv("HOME")) == NULL){ if ((homedir = getenv("HOME")) == NULL){
homedir = getpwuid(getuid())->pw_dir; homedir = getpwuid(getuid())->pw_dir;
} }
size_t L = strlen(homedir) + strlen(DEFCONF) + 2; size_t L = strlen(homedir) + strlen(DEFCONF) + 2;
fname = malloc(L); fname = malloc(L);
snprintf(fname, L, "%s/%s", homedir, DEFCONF); snprintf(fname, L, "%s/%s", homedir, DEFCONF);
mmb = My_mmap(fname); mmb = My_mmap(fname);
FREE(fname); FREE(fname);
}else mmb = My_mmap(fname); }else mmb = My_mmap(fname);
if(!mmb) return; if(!mmb) return;
char *hdrs = strdup(mmb->data); char *hdrs = strdup(mmb->data);
My_munmap(mmb); My_munmap(mmb);
char *nl = NULL; char *nl = NULL;
while((nl = strchr(hdrs, '\n'))){ while((nl = strchr(hdrs, '\n'))){
*nl = 0; *nl = 0;
list_add_record(&FITS_keys, hdrs, 1); list_add_record(&FITS_keys, hdrs, 1);
hdrs = nl + 1; hdrs = nl + 1;
} }
if(*hdrs){ // last line in file didn't have newline if(*hdrs){ // last line in file didn't have newline
list_add_record(&FITS_keys, hdrs, 1); list_add_record(&FITS_keys, hdrs, 1);
} }
} }
/** /**
@ -81,33 +80,33 @@ void get_defhdrs(char *fname){
* something like `apogee_control <parameters> filename "KEY1 = VAL1 / comment" "KEYn = VALn / comment" * something like `apogee_control <parameters> filename "KEY1 = VAL1 / comment" "KEYn = VALn / comment"
*/ */
void add_morehdrs(int argc, char **argv){ void add_morehdrs(int argc, char **argv){
int i; int i;
char buf[FLEN_CARD]; char buf[FLEN_CARD];
for(i = 0; i < argc; ++i){ // we should override parameters from default configuration file for(i = 0; i < argc; ++i){ // we should override parameters from default configuration file
char *dup = strdup(argv[i]); char *dup = strdup(argv[i]);
char *eq = strchr(dup, '='); char *eq = strchr(dup, '=');
if(eq){ if(eq){
*(eq++) = 0; *(eq++) = 0;
KeyList *found = list_find_key(FITS_keys, dup); 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 if(found) list_modify_key(FITS_keys, dup, eq, 2); // comments (if exists in new header) will be override too
else{ else{
snprintf(buf, FLEN_CARD, "%-8s= %s", dup, eq); snprintf(buf, FLEN_CARD, "%-8s= %s", dup, eq);
list_add_record(&FITS_keys, buf, 2); list_add_record(&FITS_keys, buf, 2);
} }
}else{ // comment or something else }else{ // comment or something else
list_add_record(&FITS_keys, dup, 2); list_add_record(&FITS_keys, dup, 2);
} }
FREE(dup); FREE(dup);
} }
} }
KeyList *list_get_end(KeyList *list){ KeyList *list_get_end(KeyList *list){
if(!list) return NULL; if(!list) return NULL;
KeyList *first = list; KeyList *first = list;
if(list->last) return list->last; if(list->last) return list->last;
while(list->next) list = list->next; while(list->next) list = list->next;
first->last = list; first->last = list;
return list; return list;
} }
/** /**
@ -118,49 +117,49 @@ KeyList *list_get_end(KeyList *list){
* @return pointer to created node * @return pointer to created node
*/ */
KeyList *list_add_record(KeyList **list, char *rec, int immutable){ KeyList *list_add_record(KeyList **list, char *rec, int immutable){
KeyList *node, *last; KeyList *node, *last;
if((node = (KeyList*) MALLOC(KeyList, 1)) == 0) return NULL; // allocation error if((node = (KeyList*) MALLOC(KeyList, 1)) == 0) return NULL; // allocation error
node->record = strdup(rec); // insert data node->record = strdup(rec); // insert data
node->immutable = immutable; node->immutable = immutable;
//DBG("add record %s", rec); //DBG("add record %s", rec);
if(!node->record){ if(!node->record){
/// "îÅ ÍÏÇÕ ÓËÏÐÉÒÏ×ÁÔØ ÄÁÎÎÙÅ" /// "îÅ ÍÏÇÕ ÓËÏÐÉÒÏ×ÁÔØ ÄÁÎÎÙÅ"
WARNX(_("Can't copy data")); WARNX(_("Can't copy data"));
return NULL; return NULL;
} }
if(list){ if(list){
if(*list){ // there was root node - search last if(*list){ // there was root node - search last
last = list_get_end(*list); last = list_get_end(*list);
last->next = node; // insert pointer to new node into last element in list last->next = node; // insert pointer to new node into last element in list
(*list)->last = node; (*list)->last = node;
// DBG("last node %s", (*list)->last->record); // DBG("last node %s", (*list)->last->record);
}else *list = node; }else *list = node;
} }
return node; return node;
} }
// compare keywords from `list` and `keyname` // compare keywords from `list` and `keyname`
int compare_keyw(KeyList *list, char *keyname){ int compare_keyw(KeyList *list, char *keyname){
if(!list || !keyname || !list->record) return 0; if(!list || !keyname || !list->record) return 0;
size_t L = strlen(keyname); size_t L = strlen(keyname);
if(strncmp(list->record, keyname, L) == 0){ // key found if(strncmp(list->record, keyname, L) == 0){ // key found
char *ltr = list->record + L; char *ltr = list->record + L;
while(*ltr == ' ') ++ltr; // omit spaces while(*ltr == ' ') ++ltr; // omit spaces
if(*ltr == '=') return 1; // only if there's equal sign after keyname! if(*ltr == '=') return 1; // only if there's equal sign after keyname!
} }
return 0; return 0;
} }
/** /**
* return record with given key or NULL * return record with given key or NULL
*/ */
KeyList *list_find_key(KeyList *list, char *keyname){ KeyList *list_find_key(KeyList *list, char *keyname){
if(!list || !keyname) return NULL; if(!list || !keyname) return NULL;
do{ do{
if(compare_keyw(list, keyname)) return list; if(compare_keyw(list, keyname)) return list;
list = list->next; list = list->next;
}while(list); }while(list);
return NULL; return NULL;
} }
/** /**
@ -168,24 +167,24 @@ KeyList *list_find_key(KeyList *list, char *keyname){
* @return NULL if not found or strdup`ed value * @return NULL if not found or strdup`ed value
*/ */
char *list_find_keyval(KeyList *l, char *key){ char *list_find_keyval(KeyList *l, char *key){
KeyList *list = list_find_key(l, key); KeyList *list = list_find_key(l, key);
if(!list) return NULL; if(!list) return NULL;
char *rec = strdup(list->record); char *rec = strdup(list->record);
char *val = strchr(rec, '='); char *val = strchr(rec, '=');
*val++ = 0; *val++ = 0;
char *com = strchr(val, '/'); char *com = strchr(val, '/');
if(com) *com = 0; if(com) *com = 0;
char *retval = strdup(val); char *retval = strdup(val);
FREE(rec); FREE(rec);
return retval; return retval;
} }
int getdoubleval(double *val, KeyList *list, char *key){ int getdoubleval(double *val, KeyList *list, char *key){
char *v = list_find_keyval(list, key); char *v = list_find_keyval(list, key);
if(!v) return 0; if(!v) return 0;
*val = strtod(v, NULL); *val = strtod(v, NULL);
FREE(v); FREE(v);
return 1; return 1;
} }
/** /**
@ -193,140 +192,148 @@ int getdoubleval(double *val, KeyList *list, char *key){
* return NULL if given key is absent * return NULL if given key is absent
*/ */
KeyList *list_modify_key(KeyList *list, char *key, char *newval, int immutable){ KeyList *list_modify_key(KeyList *list, char *key, char *newval, int immutable){
char buf[FLEN_CARD]; char buf[FLEN_CARD];
KeyList *rec = list_find_key(list, key); KeyList *rec = list_find_key(list, key);
if(!rec) return NULL; if(!rec) return NULL;
if(rec->immutable > immutable) return NULL; // not modify immutable records if(rec->immutable > immutable) return NULL; // not modify immutable records
rec->immutable = immutable; rec->immutable = immutable;
newval = strdup(newval); newval = strdup(newval);
char *comnt = strchr(newval, '/'); char *comnt = strchr(newval, '/');
if(comnt){ if(comnt){
*(comnt++) = 0; *(comnt++) = 0;
}else{ }else{
comnt = strchr(rec->record, '/'); comnt = strchr(rec->record, '/');
if(comnt) ++comnt; if(comnt) ++comnt;
} }
if(comnt){ if(comnt){
snprintf(buf, FLEN_CARD, "%-8s= %-21s/%s", key, newval, comnt); snprintf(buf, FLEN_CARD, "%-8s= %-21s/%s", key, newval, comnt);
}else{ }else{
snprintf(buf, FLEN_CARD, "%-8s= %s", key, newval); snprintf(buf, FLEN_CARD, "%-8s= %s", key, newval);
} }
FREE(rec->record); FREE(rec->record);
FREE(newval); FREE(newval);
DBG("modify record %s", buf); DBG("modify record %s", buf);
rec->record = strdup(buf); rec->record = strdup(buf);
return rec; return rec;
} }
void add_fits_header(int datatype, char *keyname, void *value, char *comment){ 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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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 _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)", void _fc(char* r, void* p){snprintf(r, FLEN_CARD, "(%.8f, %.8f)",
((float*)p)[0], ((float*)p)[1]);} ((float*)p)[0], ((float*)p)[1]);}
void _dc(char* r, void* p){snprintf(r, FLEN_CARD, "(%.8f, %.8f)", void _dc(char* r, void* p){snprintf(r, FLEN_CARD, "(%.8f, %.8f)",
((double*)p)[0], ((double*)p)[1]);} ((double*)p)[0], ((double*)p)[1]);}
void _log(char* r, void* p){snprintf(r, FLEN_CARD, "'%s'", (int*)p ? "true" : "false");} 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 _str(char* r, void* p){snprintf(r, FLEN_CARD, "'%s'", (char*)p);}
void _unk(char* r, void* p __attribute((unused))){sprintf(r, "unknown datatype");} void _unk(char* r, void* p __attribute((unused))){sprintf(r, "unknown datatype");}
char tmp[FLEN_CARD], res[FLEN_CARD]; char tmp[FLEN_CARD*2], res[FLEN_CARD];
void (*__)(char*, void*); void (*__)(char*, void*);
switch(datatype){ switch(datatype){
case TBIT: case TBIT:
case TBYTE: __ = _ub; break; case TBYTE: __ = _ub; break;
case TSBYTE: __ = _b; break; case TSBYTE: __ = _b; break;
case TUSHORT: __ = _us; break; case TUSHORT: __ = _us; break;
case TUINT: __ = _ui; break; case TUINT: __ = _ui; break;
case TULONG: __ = _ul; break; case TULONG: __ = _ul; break;
case TSHORT: __ = _s; break; case TSHORT: __ = _s; break;
case TINT: __ = _i; break; case TINT: __ = _i; break;
case TLONG: __ = _l; break; case TLONG: __ = _l; break;
case TLONGLONG: __ = _ll; break; case TLONGLONG: __ = _ll; break;
case TFLOAT: __ = _f; break; case TFLOAT: __ = _f; break;
case TDOUBLE: __ = _d; break; case TDOUBLE: __ = _d; break;
case TCOMPLEX: __ = _fc; break; case TCOMPLEX: __ = _fc; break;
case TDBLCOMPLEX: __ = _dc; break; case TDBLCOMPLEX: __ = _dc; break;
case TLOGICAL: __ = _log; break; case TLOGICAL: __ = _log; break;
case TSTRING: __ = _str; break; case TSTRING: __ = _str; break;
default: __ = _unk; default: __ = _unk;
} }
__(res, value); __(res, value);
KeyList *rec = list_find_key(FITS_keys, keyname); KeyList *rec = list_find_key(FITS_keys, keyname);
if(rec){ if(rec){
if(comment){ if(comment){
if(strlen(res) < 21) if(strlen(res) < 21)
snprintf(tmp, FLEN_CARD, "%-21s / %s", res, comment); snprintf(tmp, sizeof(tmp), "%-21s / %s", res, comment);
else else
snprintf(tmp, FLEN_CARD, "%s / %s", res, comment); snprintf(tmp, sizeof(tmp), "%s / %s", res, comment);
}else snprintf(tmp, FLEN_CARD, "%s", res); }else snprintf(tmp, sizeof(tmp), "%s", res);
list_modify_key(FITS_keys, keyname, tmp, 0); tmp[FLEN_CARD-1] = 0;
}else{ list_modify_key(FITS_keys, keyname, tmp, 0);
if(strlen(res) < 21) }else{
snprintf(tmp, FLEN_CARD, "%-8s= %-20s", keyname, res); if(comment){
else if(strlen(res) < 21)
snprintf(tmp, FLEN_CARD, "%-8s=%s", keyname, res); snprintf(tmp, sizeof(tmp), "%-8s= %-20s / %s", keyname, res, comment);
snprintf(res, FLEN_CARD, "%s / %s", tmp, comment); else
list_add_record(&FITS_keys, res, 0); snprintf(tmp, sizeof(tmp), "%-8s=%s / %s", keyname, res, comment);
} }else{
if(strlen(res) < 21)
snprintf(tmp, sizeof(tmp), "%-8s= %-20s", keyname, res);
else
snprintf(tmp, sizeof(tmp), "%-8s=%s", keyname, res);
}
tmp[FLEN_CARD-1] = 0;
list_add_record(&FITS_keys, tmp, 0);
}
} }
/** /**
* free list memory & set it to NULL * free list memory & set it to NULL
*/ */
void list_free(KeyList **list){ void list_free(KeyList **list){
KeyList *node = *list, *next; KeyList *node = *list, *next;
if(!list || !*list) return; if(!list || !*list) return;
do{ do{
next = node->next; next = node->next;
FREE(node->record); FREE(node->record);
free(node); free(node);
node = next; node = next;
}while(node); }while(node);
*list = NULL; *list = NULL;
} }
void free_fits_list(){ list_free(&FITS_keys); } void free_fits_list(){ list_free(&FITS_keys); }
/* /*
void list_print(KeyList *list){ void list_print(KeyList *list){
while(list){ while(list){
printf("%s\n", list->record); printf("%s\n", list->record);
list = list->next; list = list->next;
} }
} }
void show_list(){ void show_list(){
list_print(FITS_keys); list_print(FITS_keys);
} }
*/ */
void write_list(fitsfile *fp){ void write_list(fitsfile *fp){
if(FITS_keys){ // there's keys if(FITS_keys){ // there's keys
KeyList *records = FITS_keys; KeyList *records = FITS_keys;
while(records){ while(records){
char *rec = records->record; char *rec = records->record;
records = records->next; records = records->next;
if(strncmp(rec, "SIMPLE", 6) == 0 || strncmp(rec, "EXTEND", 6) == 0) // key "file does conform ..." if(strncmp(rec, "SIMPLE", 6) == 0 || strncmp(rec, "EXTEND", 6) == 0) // key "file does conform ..."
continue; continue;
// comment of obligatory key in FITS head // comment of obligatory key in FITS head
else if(strncmp(rec, "COMMENT FITS", 14) == 0 || strncmp(rec, "COMMENT and Astrophysics", 26) == 0) else if(strncmp(rec, "COMMENT FITS", 14) == 0 || strncmp(rec, "COMMENT and Astrophysics", 26) == 0)
continue; continue;
else if(strncmp(rec, "NAXIS", 5) == 0 || strncmp(rec, "BITPIX", 6) == 0) // NAXIS, NAXISxxx, BITPIX else if(strncmp(rec, "NAXIS", 5) == 0 || strncmp(rec, "BITPIX", 6) == 0) // NAXIS, NAXISxxx, BITPIX
continue; continue;
if(!test_headers){ if(!test_headers){
int status = 0; int status = 0;
fits_write_record(fp, rec, &status); fits_write_record(fp, rec, &status);
if(status) fits_report_error(stderr, status); if(status) fits_report_error(stderr, status);
}else }else
printf("%s\n", rec); printf("%s\n", rec);
} }
} }
} }
static int wcs_rdy = 0; static int wcs_rdy = 0;
@ -334,114 +341,114 @@ static int wcs_rdy = 0;
* Check if user tell some information about WCS and add it into headers * Check if user tell some information about WCS and add it into headers
*/ */
void check_wcs(){ void check_wcs(){
double cd = -5e5, crot = -5e5, rot0 = -5e5; double cd = -5e5, crot = -5e5, rot0 = -5e5;
char buf[FLEN_CARD]; char buf[FLEN_CARD];
// first correct scale: user value SCALE will fix parameter imscale // first correct scale: user value SCALE will fix parameter imscale
if(imscale < 0.) getdoubleval(&imscale, FITS_keys, "SCALE"); if(imscale < 0.) getdoubleval(&imscale, FITS_keys, "SCALE");
if(imscale < 0.){ if(imscale < 0.){
imscale = 180.*3600./M_PI / TELFOCUS / 1000000. * sqrt(pixX*pixY); // default system value imscale = 180.*3600./M_PI / TELFOCUS / 1000000. * sqrt(pixX*pixY); // default system value
} }
snprintf(buf, FLEN_CARD, "%.4f x %.4f", imscale * hbin, imscale * vbin); snprintf(buf, FLEN_CARD, "%.4f x %.4f", imscale * hbin, imscale * vbin);
WRITEKEY(TSTRING, "IMSCALE", buf, "image scale (''/Pix x ''/Pix)"); WRITEKEY(TSTRING, "IMSCALE", buf, "image scale (''/Pix x ''/Pix)");
int cnt = getdoubleval(&crval1, FITS_keys, "CRVAL1"); int cnt = getdoubleval(&crval1, FITS_keys, "CRVAL1");
cnt += getdoubleval(&crval2, FITS_keys, "CRVAL1"); cnt += getdoubleval(&crval2, FITS_keys, "CRVAL1");
cnt += getdoubleval(&crpix1, FITS_keys, "CRPIX1"); cnt += getdoubleval(&crpix1, FITS_keys, "CRPIX1");
cnt += getdoubleval(&crpix2, FITS_keys, "CRPIX2"); cnt += getdoubleval(&crpix2, FITS_keys, "CRPIX2");
cnt += getdoubleval(&cd, FITS_keys, "CD1_1"); cnt += getdoubleval(&cd, FITS_keys, "CD1_1");
cnt += getdoubleval(&crot, FITS_keys, "CROTA2"); cnt += getdoubleval(&crot, FITS_keys, "CROTA2");
cnt += getdoubleval(&rot0, FITS_keys, "ROT0"); cnt += getdoubleval(&rot0, FITS_keys, "ROT0");
if(!cnt) return; if(!cnt) return;
wcs_rdy = 1; wcs_rdy = 1;
int wcs = 2; int wcs = 2;
WRITEKEY(TINT, "WCSAXIS", &wcs, "Number of WCS axes"); WRITEKEY(TINT, "WCSAXIS", &wcs, "Number of WCS axes");
WRITEKEY(TSTRING, "CTYPE1", "RA---TAN", "RA-Gnomic projection"); WRITEKEY(TSTRING, "CTYPE1", "RA---TAN", "RA-Gnomic projection");
WRITEKEY(TSTRING, "CUNIT1", "deg", "RA units - degrees"); WRITEKEY(TSTRING, "CUNIT1", "deg", "RA units - degrees");
WRITEKEY(TSTRING, "CTYPE2", "DEC---TAN", "Decl-Gnomic projection"); WRITEKEY(TSTRING, "CTYPE2", "DEC---TAN", "Decl-Gnomic projection");
WRITEKEY(TSTRING, "CUNIT2", "deg", "Decl units - degrees"); WRITEKEY(TSTRING, "CUNIT2", "deg", "Decl units - degrees");
// CRVAL1 = / RA of reference pixel // CRVAL1 = / RA of reference pixel
if(crval1 > -4e-5) if(crval1 > -4e-5)
WRITEKEY(TDOUBLE, "CRVAL1", &crval1, "RA of reference pixel"); WRITEKEY(TDOUBLE, "CRVAL1", &crval1, "RA of reference pixel");
else crval1 = 0; else crval1 = 0;
// CRVAL2 = / Decl of reference pixel // CRVAL2 = / Decl of reference pixel
if(crval2 > -4e-5) if(crval2 > -4e-5)
WRITEKEY(TDOUBLE, "CRVAL2", &crval2, "Decl of reference pixel"); WRITEKEY(TDOUBLE, "CRVAL2", &crval2, "Decl of reference pixel");
else crval2 = 0; else crval2 = 0;
//CRPIX1 = / X reference pixel //CRPIX1 = / X reference pixel
if(crpix1 > -4e-5) if(crpix1 > -4e-5)
WRITEKEY(TDOUBLE, "CRPIX1", &crpix1, "X reference pixel"); WRITEKEY(TDOUBLE, "CRPIX1", &crpix1, "X reference pixel");
else crpix1 = 0; else crpix1 = 0;
//CRPIX2 = / Y reference pixel //CRPIX2 = / Y reference pixel
if(crpix2 > -4e-5) if(crpix2 > -4e-5)
WRITEKEY(TDOUBLE, "CRPIX2", &crpix2, "Y reference pixel"); WRITEKEY(TDOUBLE, "CRPIX2", &crpix2, "Y reference pixel");
else crpix2 = 0; else crpix2 = 0;
cnt = 0; cnt = 0;
if(cd > -4e5){ if(cd > -4e5){
++cnt; ++cnt;
WRITEKEY(TDOUBLE, "CD1_1", &cd, "rotation matrix coefficient [1,1]"); WRITEKEY(TDOUBLE, "CD1_1", &cd, "rotation matrix coefficient [1,1]");
CD[0][0] = cd; CD[0][0] = cd;
} }
if(getdoubleval(&cd, FITS_keys, "CD1_2")){ if(getdoubleval(&cd, FITS_keys, "CD1_2")){
++cnt; ++cnt;
WRITEKEY(TDOUBLE, "CD1_2", &cd, "rotation matrix coefficient [1,2]"); WRITEKEY(TDOUBLE, "CD1_2", &cd, "rotation matrix coefficient [1,2]");
CD[0][1] = cd; CD[0][1] = cd;
} }
if(getdoubleval(&cd, FITS_keys, "CD2_1")){ if(getdoubleval(&cd, FITS_keys, "CD2_1")){
++cnt; ++cnt;
WRITEKEY(TDOUBLE, "CD2_1", &cd, "rotation matrix coefficient [2,1]"); WRITEKEY(TDOUBLE, "CD2_1", &cd, "rotation matrix coefficient [2,1]");
CD[1][0] = cd; CD[1][0] = cd;
} }
if(getdoubleval(&cd, FITS_keys, "CD2_2")){ if(getdoubleval(&cd, FITS_keys, "CD2_2")){
++cnt; ++cnt;
WRITEKEY(TDOUBLE, "CD2_2", &cd, "rotation matrix coefficient [2,2]"); WRITEKEY(TDOUBLE, "CD2_2", &cd, "rotation matrix coefficient [2,2]");
CD[1][1] = cd; CD[1][1] = cd;
} }
if(cnt == 4) return; if(cnt == 4) return;
// no coefficients - use CROTA & CDELT // no coefficients - use CROTA & CDELT
cnt = 0; cnt = 0;
if(crot > -4e5){ if(crot > -4e5){
++cnt; ++cnt;
DBG("crot: %g", crot); DBG("crot: %g", crot);
WRITEKEY(TDOUBLE, "CROTA2", &crot, "North rotation angle"); WRITEKEY(TDOUBLE, "CROTA2", &crot, "North rotation angle");
} }
if(getdoubleval(&crot, FITS_keys, "CDELT1")){ if(getdoubleval(&crot, FITS_keys, "CDELT1")){
++cnt; ++cnt;
WRITEKEY(TDOUBLE, "CDELT1", &crot, "X axis scale"); WRITEKEY(TDOUBLE, "CDELT1", &crot, "X axis scale");
getdoubleval(&crot, FITS_keys, "CDELT2"); getdoubleval(&crot, FITS_keys, "CDELT2");
WRITEKEY(TDOUBLE, "CDELT2", &crot, "Y axis scale"); // use CDELT1 if user omits CDELT2 WRITEKEY(TDOUBLE, "CDELT2", &crot, "Y axis scale"); // use CDELT1 if user omits CDELT2
} }
if(cnt == 2) return; if(cnt == 2) return;
// still no coefficients - try to calculate CDx_x by user data // still no coefficients - try to calculate CDx_x by user data
double parangle, rotangle; double parangle, rotangle;
if(rot0 < -4e5) return; // no values if(rot0 < -4e5) return; // no values
if(!getdoubleval(&parangle, FITS_keys, "PARANGLE")) return; if(!getdoubleval(&parangle, FITS_keys, "PARANGLE")) return;
if(!getdoubleval(&rotangle, FITS_keys, "VAL_P")) return; if(!getdoubleval(&rotangle, FITS_keys, "VAL_P")) return;
double s, c, scx = imscale / 3600. * hbin, scy = imscale / 3600. * vbin; double s, c, scx = imscale / 3600. * hbin, scy = imscale / 3600. * vbin;
if(rot0 < 0){ // left-handed if(rot0 < 0){ // left-handed
crot = (-rot0 + parangle - rotangle)*M_PI/180; crot = (-rot0 + parangle - rotangle)*M_PI/180;
sincos(crot, &s, &c); sincos(crot, &s, &c);
CD[0][0] = -scx * c; CD[0][1] = scy * s; CD[0][0] = -scx * c; CD[0][1] = scy * s;
CD[1][0] = scx * s; CD[1][1] = scy * c; CD[1][0] = scx * s; CD[1][1] = scy * c;
}else{ // right-handed }else{ // right-handed
crot = (rot0 - parangle + rotangle)*M_PI/180; crot = (rot0 - parangle + rotangle)*M_PI/180;
sincos(crot, &s, &c); sincos(crot, &s, &c);
CD[0][0] = scx * c; CD[0][1] = -scy * s; CD[0][0] = scx * c; CD[0][1] = -scy * s;
CD[1][0] = scx * s; CD[1][1] = scy * c; 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_1", &CD[0][0], "rotation matrix coefficient [1,1]");
WRITEKEY(TDOUBLE, "CD1_2", &CD[0][1], "rotation matrix coefficient [1,2]"); 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_1", &CD[1][0], "rotation matrix coefficient [2,1]");
WRITEKEY(TDOUBLE, "CD2_2", &CD[1][1], "rotation matrix coefficient [2,2]"); WRITEKEY(TDOUBLE, "CD2_2", &CD[1][1], "rotation matrix coefficient [2,2]");
} }
// function for events.c - recalculate coordinates on image into WCS // function for events.c - recalculate coordinates on image into WCS
void calc_coords(float x, float y, double *alpha, double *delta){ void calc_coords(float x, float y, double *alpha, double *delta){
double ra, dec, dx = x - crpix1, dy = y - crpix2; double ra, dec, dx = x - crpix1, dy = y - crpix2;
if(!wcs_rdy){*alpha = 5e6; *delta = 5e6; return; } if(!wcs_rdy){*alpha = 5e6; *delta = 5e6; return; }
ra = crval1 + dx * CD[0][0] + dy * CD[0][1]; ra = crval1 + dx * CD[0][0] + dy * CD[0][1];
dec = crval2 + dx * CD[1][0] + dy * CD[1][1]; dec = crval2 + dx * CD[1][0] + dy * CD[1][1];
DBG("ra=%g, dec=%g", ra,dec); DBG("ra=%g, dec=%g", ra,dec);
if(alpha) *alpha = ra * 3600.; // hrsec if(alpha) *alpha = ra * 3600.; // hrsec
if(delta) *delta = dec * 3600.; // arcsec if(delta) *delta = dec * 3600.; // arcsec
DBG("ra=%g, dec=%g", *alpha, *delta); DBG("ra=%g, dec=%g", *alpha, *delta);
} }

View File

@ -29,7 +29,7 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} IMSOURCES)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
find_package(OpenGL) find_package(OpenGL)
find_package(GLUT) find_package(GLUT)
find_package(X11) find_package(X11 REQUIRED)
if(NOT GLUT_FOUND OR NOT OPENGL_FOUND OR NOT X11_FOUND) if(NOT GLUT_FOUND OR NOT OPENGL_FOUND OR NOT X11_FOUND)
message("GLUT library not found, image view won't be available") message("GLUT library not found, image view won't be available")
@ -143,7 +143,7 @@ else()
) )
endif(NOT DEFINED NOGETTEXT) endif(NOT DEFINED NOGETTEXT)
endif(NOT DEFINED STANDALONE) endif(NOT DEFINED STANDALONE)
target_link_libraries(${IMLIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} -lm -lpthread) target_link_libraries(${IMLIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${X11_LIBRARIES} -lm -lpthread)
include_directories(${${IMLIB}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ..) include_directories(${${IMLIB}_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ..)
link_directories(${${IMLIB}_LIBRARY_DIRS}) link_directories(${${IMLIB}_LIBRARY_DIRS})
endif(NOT GLUT_FOUND OR NOT OPENGL_FOUND OR NOT X11_FOUND) endif(NOT GLUT_FOUND OR NOT OPENGL_FOUND OR NOT X11_FOUND)

View File

@ -40,92 +40,92 @@ void Resize(int width, int height);
* calculate window properties on creating & resizing * calculate window properties on creating & resizing
*/ */
void calc_win_props(windowData *win, GLfloat *Wortho, GLfloat *Hortho){ void calc_win_props(windowData *win, GLfloat *Wortho, GLfloat *Hortho){
if(!win || ! win->image) return; if(!win || ! win->image) return;
double a, A, w, h, W, H; double a, A, w, h, W, H;
double Zoom = win->zoom; double Zoom = win->zoom;
w = (double)win->image->w / 2.; w = (double)win->image->w / 2.;
h = (double)win->image->h / 2.; h = (double)win->image->h / 2.;
W = (double)win->w; W = (double)win->w;
H = (double)win->h; H = (double)win->h;
A = W / H; A = W / H;
a = w / h; a = w / h;
if(A > a){ // now W & H are parameters for glOrtho if(A > a){ // now W & H are parameters for glOrtho
win->Daspect = h / H * 2.; win->Daspect = h / H * 2.;
W = h * A; H = h; W = h * A; H = h;
}else{ }else{
win->Daspect = w / W * 2.; win->Daspect = w / W * 2.;
H = w / A; W = w; H = w / A; W = w;
} }
if(Wortho) *Wortho = W; if(Wortho) *Wortho = W;
if(Hortho) *Hortho = H; if(Hortho) *Hortho = H;
// calculate coordinates of center // calculate coordinates of center
win->x0 = W/Zoom - w + win->x / Zoom; win->x0 = W/Zoom - w + win->x / Zoom;
win->y0 = H / Zoom + h - win->y / Zoom; win->y0 = H / Zoom + h - win->y / Zoom;
} }
/** /**
* create window & run main loop * create window & run main loop
*/ */
void createWindow(windowData *win){ void createWindow(windowData *win){
FNAME(); FNAME();
if(!initialized) return; if(!initialized) return;
if(!win) return; if(!win) return;
int w = win->w, h = win->h; int w = win->w, h = win->h;
DBG("create window with title %s", win->title); DBG("create window with title %s", win->title);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(w, h); glutInitWindowSize(w, h);
win->GL_ID = glutCreateWindow(win->title); win->GL_ID = glutCreateWindow(win->title);
DBG("created GL_ID=%d", win->GL_ID); DBG("created GL_ID=%d", win->GL_ID);
glutReshapeFunc(Resize); glutReshapeFunc(Resize);
glutDisplayFunc(RedrawWindow); glutDisplayFunc(RedrawWindow);
glutKeyboardFunc(keyPressed); glutKeyboardFunc(keyPressed);
glutSpecialFunc(keySpPressed); glutSpecialFunc(keySpPressed);
glutMouseFunc(mousePressed); glutMouseFunc(mousePressed);
glutMotionFunc(mouseMove); glutMotionFunc(mouseMove);
glutIdleFunc(NULL); glutIdleFunc(NULL);
DBG("init textures"); DBG("init textures");
glGenTextures(1, &(win->Tex)); glGenTextures(1, &(win->Tex));
win->zoom = 1.; win->zoom = 1.;
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, win->Tex); glBindTexture(GL_TEXTURE_2D, win->Tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, win->image->w, win->image->h, 0, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, win->image->w, win->image->h, 0,
GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata); GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
totWindows++; totWindows++;
createMenu(win->GL_ID); createMenu(win->GL_ID);
DBG("OK, total opened windows: %d", totWindows); DBG("OK, total opened windows: %d", totWindows);
} }
int killwindow(int GL_ID){ int killwindow(int GL_ID){
DBG("try to kill win GL_ID=%d", GL_ID); DBG("try to kill win GL_ID=%d", GL_ID);
windowData *win; windowData *win;
win = searchWindow_byGLID(GL_ID); win = searchWindow_byGLID(GL_ID);
if(!win) return 0; if(!win) return 0;
glutSetWindow(GL_ID); // obviously set window (for closing from menu) glutSetWindow(GL_ID); // obviously set window (for closing from menu)
if(!win->killthread){ if(!win->killthread){
pthread_mutex_lock(&win->mutex); pthread_mutex_lock(&win->mutex);
// say changed thread to die // say changed thread to die
win->killthread = 1; win->killthread = 1;
pthread_mutex_unlock(&win->mutex); pthread_mutex_unlock(&win->mutex);
DBG("wait for changed thread"); DBG("wait for changed thread");
pthread_join(win->thread, NULL); // wait while thread dies pthread_join(win->thread, NULL); // wait while thread dies
} }
if(win->menu) glutDestroyMenu(win->menu); if(win->menu) glutDestroyMenu(win->menu);
glutDestroyWindow(win->GL_ID); glutDestroyWindow(win->GL_ID);
win->GL_ID = 0; // reset for forEachWindow() win->GL_ID = 0; // reset for forEachWindow()
DBG("destroy texture %d", win->Tex); DBG("destroy texture %d", win->Tex);
glDeleteTextures(1, &(win->Tex)); glDeleteTextures(1, &(win->Tex));
glFinish(); glFinish();
if(!removeWindow(win->ID)) WARNX(_("Error removing from list")); if(!removeWindow(win->ID)) WARNX(_("Error removing from list"));
totWindows--; totWindows--;
return 1; return 1;
} }
/** /**
@ -135,89 +135,90 @@ int killwindow(int GL_ID){
* @return 1 in case of OK, 0 if fault * @return 1 in case of OK, 0 if fault
*/ */
int destroyWindow(int window, winIdType type){ int destroyWindow(int window, winIdType type){
if(!initialized) return 0; if(!initialized) return 0;
int r = 0; int r = 0;
DBG("lock"); DBG("lock");
pthread_mutex_lock(&winini_mutex); pthread_mutex_lock(&winini_mutex);
DBG("locked"); DBG("locked");
if(type == INNER){ if(type == INNER){
windowData *win = searchWindow(window); windowData *win = searchWindow(window);
if(win) r = killwindow(win->GL_ID); if(win) r = killwindow(win->GL_ID);
}else }else
r = killwindow(window); r = killwindow(window);
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
DBG("window killed"); DBG("window killed");
return r; return r;
} }
/** /**
* asynchroneous destroying - for using from menu * asynchroneous destroying - for using from menu
*/ */
void destroyWindow_async(int window_GL_ID){ void destroyWindow_async(int window_GL_ID){
pthread_mutex_lock(&winini_mutex); pthread_mutex_lock(&winini_mutex);
wannakill_GL_ID = window_GL_ID; wannakill_GL_ID = window_GL_ID;
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
} }
void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){ void renderBitmapString(float x, float y, void *font, char *string, GLubyte *color){
if(!initialized) return; if(!initialized) return;
char *c; char *c;
int x1=x, W=0; int x1=x, W=0;
for(c = string; *c; c++){ for(c = string; *c; c++){
W += glutBitmapWidth(font,*c);// + 1; W += glutBitmapWidth(font,*c);// + 1;
} }
x1 -= W/2; x1 -= W/2;
glColor3ubv(color); glColor3ubv(color);
glLoadIdentity(); glLoadIdentity();
glTranslatef(0.,0., -150); glTranslatef(0.,0., -150);
//glTranslatef(x,y, -4000.); //glTranslatef(x,y, -4000.);
for (c = string; *c != '\0'; c++){ for (c = string; *c != '\0'; c++){
glColor3ubv(color); glColor3ubv(color);
glRasterPos2f(x1,y); glRasterPos2f(x1,y);
glutBitmapCharacter(font, *c); glutBitmapCharacter(font, *c);
//glutStrokeCharacter(GLUT_STROKE_ROMAN, *c); //glutStrokeCharacter(GLUT_STROKE_ROMAN, *c);
x1 = x1 + glutBitmapWidth(font,*c);// + 1; x1 = x1 + glutBitmapWidth(font,*c);// + 1;
} }
} }
void redisplay(int GL_ID){ void redisplay(int GL_ID){
if(!initialized) return; if(!initialized) return;
glutSetWindow(GL_ID); glutSetWindow(GL_ID);
glutPostRedisplay(); glutPostRedisplay();
} }
void RedrawWindow(){ void RedrawWindow(){
if(!initialized) return; if(!initialized) return;
int window; int window;
window = glutGetWindow(); window = glutGetWindow();
windowData *win = searchWindow_byGLID(window); windowData *win = searchWindow_byGLID(window);
if(!win) return; if(!win) return;
if(pthread_mutex_trylock(&win->mutex) != 0) return; if(pthread_mutex_trylock(&win->mutex) != 0) return;
int w = win->image->w, h = win->image->h; int w = win->image->w, h = win->image->h;
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); glLoadIdentity();
glTranslatef(win->x, win->y, 0.); glTranslatef(win->x, win->y, 0.);
glScalef(-win->zoom, -win->zoom, 1.); glScalef(-win->zoom, -win->zoom, 1.);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, win->Tex); glBindTexture(GL_TEXTURE_2D, win->Tex);
if(win->image->changed){ if(win->image->changed){
DBG("change texture as image have been changed"); DBG("change texture as image have been changed");
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, win->image->rawdata);
win->image->changed = 0; win->image->changed = 0;
} }
w /= 2.; h /= 2.; w /= 2.; h /= 2.;
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-w, -h ); glTexCoord2f(1.0f, 1.0f); glVertex2f( -w, -h ); // top right
glTexCoord2f(1.0f, 0.0f); glVertex2f( w, -h ); glTexCoord2f(1.0f, 0.0f); glVertex2f( -w, h ); // bottom right
glTexCoord2f(1.0f, 1.0f); glVertex2f( w, h ); glTexCoord2f(0.0f, 0.0f); glVertex2f(w, h ); // bottom left
glTexCoord2f(0.0f, 1.0f); glVertex2f(-w, h ); glTexCoord2f(0.0f, 1.0f); glVertex2f(w, -h ); // top left
glEnd();
glDisable(GL_TEXTURE_2D); glEnd();
glFinish(); glDisable(GL_TEXTURE_2D);
glutSwapBuffers(); glFinish();
pthread_mutex_unlock(&win->mutex); glutSwapBuffers();
pthread_mutex_unlock(&win->mutex);
} }
/** /**
@ -225,49 +226,49 @@ void RedrawWindow(){
* waits for global signals to create windows & make other actions * waits for global signals to create windows & make other actions
*/ */
void *Redraw(_U_ void *arg){ void *Redraw(_U_ void *arg){
while(1){ while(1){
pthread_mutex_lock(&winini_mutex); pthread_mutex_lock(&winini_mutex);
if(!initialized){ if(!initialized){
DBG("!initialized"); DBG("!initialized");
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
pthread_exit(NULL); pthread_exit(NULL);
} }
if(wannacreate){ // someone asks to create window if(wannacreate){ // someone asks to create window
DBG("call for window creating, id: %d", wininiptr->ID); DBG("call for window creating, id: %d", wininiptr->ID);
createWindow(wininiptr); createWindow(wininiptr);
DBG("done!"); DBG("done!");
wininiptr = NULL; wininiptr = NULL;
wannacreate = 0; wannacreate = 0;
} }
if(wannakill_GL_ID){ if(wannakill_GL_ID){
usleep(10000); // wait a little to be sure that caller is closed usleep(10000); // wait a little to be sure that caller is closed
killwindow(wannakill_GL_ID); killwindow(wannakill_GL_ID);
wannakill_GL_ID = 0; wannakill_GL_ID = 0;
} }
forEachWindow(redisplay); forEachWindow(redisplay);
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
if(totWindows) glutMainLoopEvent(); // process actions if there are windows if(totWindows) glutMainLoopEvent(); // process actions if there are windows
usleep(10000); usleep(10000);
} }
return NULL; return NULL;
} }
void Resize(int width, int height){ void Resize(int width, int height){
if(!initialized) return; if(!initialized) return;
int window = glutGetWindow(); int window = glutGetWindow();
windowData *win = searchWindow_byGLID(window); windowData *win = searchWindow_byGLID(window);
if(!win) return; if(!win) return;
glutReshapeWindow(width, height); glutReshapeWindow(width, height);
win->w = width; win->w = width;
win->h = height; win->h = height;
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
GLfloat W, H; GLfloat W, H;
calc_win_props(win, &W, &H); calc_win_props(win, &W, &H);
glOrtho(-W,W, -H,H, -1., 1.); glOrtho(-W,W, -H,H, -1., 1.);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
} }
/** /**
@ -280,96 +281,96 @@ void Resize(int width, int height){
* or allocated outside data * or allocated outside data
*/ */
windowData *createGLwin(char *title, int w, int h, rawimage *rawdata){ windowData *createGLwin(char *title, int w, int h, rawimage *rawdata){
FNAME(); FNAME();
if(!initialized) return NULL; if(!initialized) return NULL;
windowData *win = MALLOC(windowData, 1); windowData *win = MALLOC(windowData, 1);
if(!addWindow(win)){ if(!addWindow(win)){
FREE(win); FREE(win);
return NULL; return NULL;
} }
rawimage *raw; rawimage *raw;
if(rawdata){ if(rawdata){
raw = rawdata; raw = rawdata;
}else{ }else{
raw = MALLOC(rawimage, 1); raw = MALLOC(rawimage, 1);
if(raw){ if(raw){
raw->rawdata = MALLOC(GLubyte, w*h*3); raw->rawdata = MALLOC(GLubyte, w*h*3);
raw->w = w; raw->w = w;
raw->h = h; raw->h = h;
raw->changed = 1; raw->changed = 1;
// raw->protected is zero automatically // raw->protected is zero automatically
} }
} }
if(!raw || !raw->rawdata){ if(!raw || !raw->rawdata){
free(raw); free(raw);
return NULL; return NULL;
} }
win->title = strdup(title); win->title = strdup(title);
win->image = raw; win->image = raw;
if(pthread_mutex_init(&win->mutex, NULL)){ if(pthread_mutex_init(&win->mutex, NULL)){
WARN(_("Can't init mutex!")); WARN(_("Can't init mutex!"));
removeWindow(win->ID); removeWindow(win->ID);
return NULL; return NULL;
} }
win->w = w; win->w = w;
win->h = h; win->h = h;
win->zoom = 1.; win->zoom = 1.;
while(wannacreate); // wait if there was another creating while(wannacreate); // wait if there was another creating
pthread_mutex_lock(&winini_mutex); pthread_mutex_lock(&winini_mutex);
wininiptr = win; wininiptr = win;
wannacreate = 1; wannacreate = 1;
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
DBG("wait for creatin"); DBG("wait for creatin");
while(wannacreate); // wait until window created from main thread while(wannacreate); // wait until window created from main thread
DBG("window created"); DBG("window created");
return win; return win;
} }
/** /**
* Init freeGLUT * Init freeGLUT
*/ */
void imageview_init(){ void imageview_init(){
FNAME(); FNAME();
char *v[] = {PROJNAME, NULL}; char *v[] = {PROJNAME, NULL};
int c = 1; int c = 1;
static int glutnotinited = 1; static int glutnotinited = 1;
if(initialized){ if(initialized){
// "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!" // "õÖÅ ÉÎÉÃÉÁÌÉÚÉÒÏ×ÁÎÏ!"
WARNX(_("Already initialized!")); WARNX(_("Already initialized!"));
return; return;
} }
if(glutnotinited){ if(glutnotinited){
DBG("init"); DBG("init");
XInitThreads(); // we need it for threaded windows XInitThreads(); // we need it for threaded windows
glutInit(&c, v); glutInit(&c, v);
glutnotinited = 0; glutnotinited = 0;
} }
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
pthread_create(&GLUTthread, NULL, &Redraw, NULL); pthread_create(&GLUTthread, NULL, &Redraw, NULL);
initialized = 1; initialized = 1;
} }
void killwindow_v(int GL_ID){ void killwindow_v(int GL_ID){
DBG("GL_ID: %d", GL_ID); DBG("GL_ID: %d", GL_ID);
killwindow(GL_ID); killwindow(GL_ID);
} }
/** /**
* Close all opened windows and terminate main GLUT thread * Close all opened windows and terminate main GLUT thread
*/ */
void clear_GL_context(){ void clear_GL_context(){
FNAME(); FNAME();
if(!initialized) return; if(!initialized) return;
DBG("lock"); DBG("lock");
pthread_mutex_lock(&winini_mutex); pthread_mutex_lock(&winini_mutex);
initialized = 0; initialized = 0;
DBG("locked"); DBG("locked");
// kill main GLUT thread // kill main GLUT thread
pthread_mutex_unlock(&winini_mutex); pthread_mutex_unlock(&winini_mutex);
forEachWindow(killwindow_v); forEachWindow(killwindow_v);
DBG("join"); DBG("join");
pthread_join(GLUTthread, NULL); // wait while main thread exits pthread_join(GLUTthread, NULL); // wait while main thread exits
DBG("main GL thread cancelled"); DBG("main GL thread cancelled");
} }
@ -379,21 +380,21 @@ void clear_GL_context(){
* X,Y - coordinates of appropriate point at picture * X,Y - coordinates of appropriate point at picture
*/ */
void conv_mouse_to_image_coords(int x, int y, void conv_mouse_to_image_coords(int x, int y,
float *X, float *Y, float *X, float *Y,
windowData *window){ windowData *window){
float a = window->Daspect / window->zoom; float a = window->Daspect / window->zoom;
*X = x * a - window->x0; *X = x * a - window->x0;
*Y = window->y0 - y * a; *Y = window->y0 - y * a;
} }
void conv_image_to_mouse_coords(float X, float Y, void conv_image_to_mouse_coords(float X, float Y,
int *x, int *y, int *x, int *y,
windowData *window){ windowData *window){
float a = window->zoom / window->Daspect; float a = window->zoom / window->Daspect;
*x = (X + window->x0) * a; *x = (X + window->x0) * a;
*y = (window->y0 - Y) * a; *y = (window->y0 - Y) * a;
} }
int get_windows_amount(){ int get_windows_amount(){
return totWindows; return totWindows;
} }

1
netcamID Normal file
View File

@ -0,0 +1 @@
apogee_control -M interface=ethernet,deviceType=camera,address=192.168.99.121,port=80,mac=000951ffffff81ffffffed22,interfaceStatus=Available,id=0x1a3,firmwareRev=0x132,model=Aspen-16M

1265
takepic.c

File diff suppressed because it is too large Load Diff

View File

@ -24,28 +24,28 @@
#ifndef _XOPEN_SOURCE #ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 501 #define _XOPEN_SOURCE 501
#endif #endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <err.h>
#include <limits.h>
#include <errno.h>
#include <math.h>
#include <stdbool.h>
#include <fitsio.h>
#include <libintl.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <fitsio.h>
#include <libapogee.h>
#include <libintl.h>
#include <limits.h>
#include <math.h>
#ifdef USEPNG #ifdef USEPNG
#include <png.h> #include <png.h>
#endif /* USEPNG */ #endif /* USEPNG */
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <libapogee.h>
#ifndef GETTEXT_PACKAGE #ifndef GETTEXT_PACKAGE
#define GETTEXT_PACKAGE "apogee_control" #define GETTEXT_PACKAGE "apogee_control"
@ -61,16 +61,16 @@
* BTA focal ratio 24.024 m * BTA focal ratio 24.024 m
*/ */
#ifndef TELLAT #ifndef TELLAT
#define TELLAT (43.6535278) #define TELLAT (43.6535278)
#endif #endif
#ifndef TELLONG #ifndef TELLONG
#define TELLONG (41.44143375) #define TELLONG (41.44143375)
#endif #endif
#ifndef TELALT #ifndef TELALT
#define TELALT (2070.0) #define TELALT (2070.0)
#endif #endif
#ifndef TELFOCUS #ifndef TELFOCUS
#define TELFOCUS (24.024) #define TELFOCUS (24.024)
#endif #endif
// filename for default headers (in ~) // filename for default headers (in ~)
#ifndef DEFCONF #ifndef DEFCONF
@ -80,8 +80,8 @@ extern int test_headers;
extern const char *__progname; extern const char *__progname;
#define info(format, args...) do{ \ #define info(format, args...) do{ \
printf("%s: ", __progname); \ printf("%s: ", __progname); \
printf(format, ## args); \ printf(format, ## args); \
printf("\n");}while(0) printf("\n");}while(0)
#endif // __TAKEPIC_H__ #endif // __TAKEPIC_H__

1089
usage.c

File diff suppressed because it is too large Load Diff