mirror of
https://github.com/eddyem/bta-image-model.git
synced 2025-12-06 02:35:21 +03:00
copy
This commit is contained in:
commit
8602fda187
34
CMakeLists.txt
Normal file
34
CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
set(PROJ mkHartmann)
|
||||
set(PROJ_VER "0.0.1")
|
||||
project(${PROJ})
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
#set(DEBUG 1) # Comment out this line in release mode
|
||||
if(NOT DEFINED NO_CUDA)
|
||||
message("Try to use CUDA")
|
||||
find_package(CUDA)
|
||||
if(CUDA_FOUND)
|
||||
add_definitions(-DCUDA_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
if(NOT DEFINED PROCESSOR_COUNT)
|
||||
set(PROCESSOR_COUNT 2) # by default 2 cores
|
||||
set(cpuinfo_file "/proc/cpuinfo")
|
||||
if(EXISTS "${cpuinfo_file}")
|
||||
file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
|
||||
list(LENGTH procs PROCESSOR_COUNT)
|
||||
endif()
|
||||
endif()
|
||||
add_definitions(-DTHREAD_NUMBER=${PROCESSOR_COUNT})
|
||||
message("In multithreaded operations will use ${PROCESSOR_COUNT} threads")
|
||||
|
||||
# fix invalid install paths
|
||||
if(DEFINED CMAKE_INSTALL_PREFIX AND CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
|
||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
||||
endif()
|
||||
# change path by user's wish
|
||||
if(NOT DEFINED LOCALEDIR)
|
||||
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
|
||||
endif()
|
||||
set(CMAKE_INSTALL_LOCALEDIR "${LOCALEDIR}/ru/LC_MESSAGES")
|
||||
subdirs(src)
|
||||
4
RUN
Executable file
4
RUN
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
[ -d "tmp" ] && rm -rf tmp
|
||||
mkdir tmp && cd tmp && cmake .. -DCMAKE_INSTALL_PREFIX=/home/eddy -DLOCALEDIR=/home/eddy/.local/share/locale -DDEBUG=1
|
||||
ln -s ../mask/holes.json
|
||||
17
mask/README.fmt
Normal file
17
mask/README.fmt
Normal file
@ -0,0 +1,17 @@
|
||||
JSON format:
|
||||
|
||||
global object MUST consist field "Z" or "maskz" with Z-coordinate of mask
|
||||
|
||||
it CAN contain global fields (common to all holes) such as in holes array
|
||||
its field bbox (if exists) HAVE TO BE GLOBAL convex bbox of all holes!
|
||||
|
||||
it MUST contain at least one hole object (or hole array)
|
||||
|
||||
fields of "hole":
|
||||
"shape" - shape of hole (could be "square" and "round" or "ellipse")
|
||||
"radius" - scalar or array[2] with radius parameter
|
||||
"center" - array[2] with coordinates of hole's center
|
||||
"bbox" - array[4] with bounding box of a hole
|
||||
|
||||
independently from shape any hole can consist both fields "radius" and "center" or single field "bbox"
|
||||
|
||||
264
mask/holes.json
Normal file
264
mask/holes.json
Normal file
@ -0,0 +1,264 @@
|
||||
{
|
||||
"maskz": 20.0,
|
||||
"shape": "round", "radius": 0.007500,
|
||||
"holes": [
|
||||
{ "ring": 0, "number": 0, "center": [ 0.1742, 0.0172 ] },
|
||||
{ "ring": 0, "number": 1, "center": [ 0.1675, 0.0508 ] },
|
||||
{ "ring": 0, "number": 2, "center": [ 0.1543, 0.0825 ] },
|
||||
{ "ring": 0, "number": 3, "center": [ 0.1353, 0.1110 ] },
|
||||
{ "ring": 0, "number": 4, "center": [ 0.1110, 0.1353 ] },
|
||||
{ "ring": 0, "number": 5, "center": [ 0.0825, 0.1543 ] },
|
||||
{ "ring": 0, "number": 6, "center": [ 0.0508, 0.1675 ] },
|
||||
{ "ring": 0, "number": 7, "center": [ 0.0172, 0.1742 ] },
|
||||
{ "ring": 0, "number": 8, "center": [ -0.0172, 0.1742 ] },
|
||||
{ "ring": 0, "number": 9, "center": [ -0.0508, 0.1675 ] },
|
||||
{ "ring": 0, "number": 10, "center": [ -0.0825, 0.1543 ] },
|
||||
{ "ring": 0, "number": 11, "center": [ -0.1110, 0.1353 ] },
|
||||
{ "ring": 0, "number": 12, "center": [ -0.1353, 0.1110 ] },
|
||||
{ "ring": 0, "number": 13, "center": [ -0.1543, 0.0825 ] },
|
||||
{ "ring": 0, "number": 14, "center": [ -0.1675, 0.0508 ] },
|
||||
{ "ring": 0, "number": 15, "center": [ -0.1742, 0.0172 ] },
|
||||
{ "ring": 0, "number": 16, "center": [ -0.1742, -0.0172 ] },
|
||||
{ "ring": 0, "number": 17, "center": [ -0.1675, -0.0508 ] },
|
||||
{ "ring": 0, "number": 18, "center": [ -0.1543, -0.0825 ] },
|
||||
{ "ring": 0, "number": 19, "center": [ -0.1353, -0.1110 ] },
|
||||
{ "ring": 0, "number": 20, "center": [ -0.1110, -0.1353 ] },
|
||||
{ "ring": 0, "number": 21, "center": [ -0.0825, -0.1543 ] },
|
||||
{ "ring": 0, "number": 22, "center": [ -0.0508, -0.1675 ] },
|
||||
{ "ring": 0, "number": 23, "center": [ -0.0172, -0.1742 ] },
|
||||
{ "ring": 0, "number": 24, "center": [ 0.0172, -0.1742 ] },
|
||||
{ "ring": 0, "number": 25, "center": [ 0.0508, -0.1675 ] },
|
||||
{ "ring": 0, "number": 26, "center": [ 0.0825, -0.1543 ] },
|
||||
{ "ring": 0, "number": 27, "center": [ 0.1110, -0.1353 ] },
|
||||
{ "ring": 0, "number": 28, "center": [ 0.1353, -0.1110 ] },
|
||||
{ "ring": 0, "number": 29, "center": [ 0.1543, -0.0825 ] },
|
||||
{ "ring": 0, "number": 30, "center": [ 0.1675, -0.0508 ] },
|
||||
{ "ring": 0, "number": 31, "center": [ 0.1742, -0.0172 ] },
|
||||
{ "ring": 1, "number": 0, "center": [ 0.2458, 0.0242 ] },
|
||||
{ "ring": 1, "number": 1, "center": [ 0.2364, 0.0717 ] },
|
||||
{ "ring": 1, "number": 2, "center": [ 0.2178, 0.1164 ] },
|
||||
{ "ring": 1, "number": 3, "center": [ 0.1909, 0.1567 ] },
|
||||
{ "ring": 1, "number": 4, "center": [ 0.1567, 0.1909 ] },
|
||||
{ "ring": 1, "number": 5, "center": [ 0.1164, 0.2178 ] },
|
||||
{ "ring": 1, "number": 6, "center": [ 0.0717, 0.2364 ] },
|
||||
{ "ring": 1, "number": 7, "center": [ 0.0242, 0.2458 ] },
|
||||
{ "ring": 1, "number": 8, "center": [ -0.0242, 0.2458 ] },
|
||||
{ "ring": 1, "number": 9, "center": [ -0.0717, 0.2364 ] },
|
||||
{ "ring": 1, "number": 10, "center": [ -0.1164, 0.2178 ] },
|
||||
{ "ring": 1, "number": 11, "center": [ -0.1567, 0.1909 ] },
|
||||
{ "ring": 1, "number": 12, "center": [ -0.1909, 0.1567 ] },
|
||||
{ "ring": 1, "number": 13, "center": [ -0.2178, 0.1164 ] },
|
||||
{ "ring": 1, "number": 14, "center": [ -0.2364, 0.0717 ] },
|
||||
{ "ring": 1, "number": 15, "center": [ -0.2458, 0.0242 ] },
|
||||
{ "ring": 1, "number": 16, "center": [ -0.2458, -0.0242 ] },
|
||||
{ "ring": 1, "number": 17, "center": [ -0.2364, -0.0717 ] },
|
||||
{ "ring": 1, "number": 18, "center": [ -0.2178, -0.1164 ] },
|
||||
{ "ring": 1, "number": 19, "center": [ -0.1909, -0.1567 ] },
|
||||
{ "ring": 1, "number": 20, "center": [ -0.1567, -0.1909 ] },
|
||||
{ "ring": 1, "number": 21, "center": [ -0.1164, -0.2178 ] },
|
||||
{ "ring": 1, "number": 22, "center": [ -0.0717, -0.2364 ] },
|
||||
{ "ring": 1, "number": 23, "center": [ -0.0242, -0.2458 ] },
|
||||
{ "ring": 1, "number": 24, "center": [ 0.0242, -0.2458 ] },
|
||||
{ "ring": 1, "number": 25, "center": [ 0.0717, -0.2364 ] },
|
||||
{ "ring": 1, "number": 26, "center": [ 0.1164, -0.2178 ] },
|
||||
{ "ring": 1, "number": 27, "center": [ 0.1567, -0.1909 ] },
|
||||
{ "ring": 1, "number": 28, "center": [ 0.1909, -0.1567 ] },
|
||||
{ "ring": 1, "number": 29, "center": [ 0.2178, -0.1164 ] },
|
||||
{ "ring": 1, "number": 30, "center": [ 0.2364, -0.0717 ] },
|
||||
{ "ring": 1, "number": 31, "center": [ 0.2458, -0.0242 ] },
|
||||
{ "ring": 2, "number": 0, "center": [ 0.2936, 0.0289 ] },
|
||||
{ "ring": 2, "number": 1, "center": [ 0.2823, 0.0856 ] },
|
||||
{ "ring": 2, "number": 2, "center": [ 0.2602, 0.1391 ] },
|
||||
{ "ring": 2, "number": 3, "center": [ 0.2280, 0.1871 ] },
|
||||
{ "ring": 2, "number": 4, "center": [ 0.1871, 0.2280 ] },
|
||||
{ "ring": 2, "number": 5, "center": [ 0.1391, 0.2602 ] },
|
||||
{ "ring": 2, "number": 6, "center": [ 0.0856, 0.2823 ] },
|
||||
{ "ring": 2, "number": 7, "center": [ 0.0289, 0.2936 ] },
|
||||
{ "ring": 2, "number": 8, "center": [ -0.0289, 0.2936 ] },
|
||||
{ "ring": 2, "number": 9, "center": [ -0.0856, 0.2823 ] },
|
||||
{ "ring": 2, "number": 10, "center": [ -0.1391, 0.2602 ] },
|
||||
{ "ring": 2, "number": 11, "center": [ -0.1871, 0.2280 ] },
|
||||
{ "ring": 2, "number": 12, "center": [ -0.2280, 0.1871 ] },
|
||||
{ "ring": 2, "number": 13, "center": [ -0.2602, 0.1391 ] },
|
||||
{ "ring": 2, "number": 14, "center": [ -0.2823, 0.0856 ] },
|
||||
{ "ring": 2, "number": 15, "center": [ -0.2936, 0.0289 ] },
|
||||
{ "ring": 2, "number": 16, "center": [ -0.2936, -0.0289 ] },
|
||||
{ "ring": 2, "number": 17, "center": [ -0.2823, -0.0856 ] },
|
||||
{ "ring": 2, "number": 18, "center": [ -0.2602, -0.1391 ] },
|
||||
{ "ring": 2, "number": 19, "center": [ -0.2280, -0.1871 ] },
|
||||
{ "ring": 2, "number": 20, "center": [ -0.1871, -0.2280 ] },
|
||||
{ "ring": 2, "number": 21, "center": [ -0.1391, -0.2602 ] },
|
||||
{ "ring": 2, "number": 22, "center": [ -0.0856, -0.2823 ] },
|
||||
{ "ring": 2, "number": 23, "center": [ -0.0289, -0.2936 ] },
|
||||
{ "ring": 2, "number": 24, "center": [ 0.0289, -0.2936 ] },
|
||||
{ "ring": 2, "number": 25, "center": [ 0.0856, -0.2823 ] },
|
||||
{ "ring": 2, "number": 26, "center": [ 0.1391, -0.2602 ] },
|
||||
{ "ring": 2, "number": 27, "center": [ 0.1871, -0.2280 ] },
|
||||
{ "ring": 2, "number": 28, "center": [ 0.2280, -0.1871 ] },
|
||||
{ "ring": 2, "number": 29, "center": [ 0.2602, -0.1391 ] },
|
||||
{ "ring": 2, "number": 30, "center": [ 0.2823, -0.0856 ] },
|
||||
{ "ring": 2, "number": 31, "center": [ 0.2936, -0.0289 ] },
|
||||
{ "ring": 3, "number": 0, "center": [ 0.3384, 0.0333 ] },
|
||||
{ "ring": 3, "number": 1, "center": [ 0.3254, 0.0987 ] },
|
||||
{ "ring": 3, "number": 2, "center": [ 0.2999, 0.1603 ] },
|
||||
{ "ring": 3, "number": 3, "center": [ 0.2628, 0.2157 ] },
|
||||
{ "ring": 3, "number": 4, "center": [ 0.2157, 0.2628 ] },
|
||||
{ "ring": 3, "number": 5, "center": [ 0.1603, 0.2999 ] },
|
||||
{ "ring": 3, "number": 6, "center": [ 0.0987, 0.3254 ] },
|
||||
{ "ring": 3, "number": 7, "center": [ 0.0333, 0.3384 ] },
|
||||
{ "ring": 3, "number": 8, "center": [ -0.0333, 0.3384 ] },
|
||||
{ "ring": 3, "number": 9, "center": [ -0.0987, 0.3254 ] },
|
||||
{ "ring": 3, "number": 10, "center": [ -0.1603, 0.2999 ] },
|
||||
{ "ring": 3, "number": 11, "center": [ -0.2157, 0.2628 ] },
|
||||
{ "ring": 3, "number": 12, "center": [ -0.2628, 0.2157 ] },
|
||||
{ "ring": 3, "number": 13, "center": [ -0.2999, 0.1603 ] },
|
||||
{ "ring": 3, "number": 14, "center": [ -0.3254, 0.0987 ] },
|
||||
{ "ring": 3, "number": 15, "center": [ -0.3384, 0.0333 ] },
|
||||
{ "ring": 3, "number": 16, "center": [ -0.3384, -0.0333 ] },
|
||||
{ "ring": 3, "number": 17, "center": [ -0.3254, -0.0987 ] },
|
||||
{ "ring": 3, "number": 18, "center": [ -0.2999, -0.1603 ] },
|
||||
{ "ring": 3, "number": 19, "center": [ -0.2628, -0.2157 ] },
|
||||
{ "ring": 3, "number": 20, "center": [ -0.2157, -0.2628 ] },
|
||||
{ "ring": 3, "number": 21, "center": [ -0.1603, -0.2999 ] },
|
||||
{ "ring": 3, "number": 22, "center": [ -0.0987, -0.3254 ] },
|
||||
{ "ring": 3, "number": 23, "center": [ -0.0333, -0.3384 ] },
|
||||
{ "ring": 3, "number": 24, "center": [ 0.0333, -0.3384 ] },
|
||||
{ "ring": 3, "number": 25, "center": [ 0.0987, -0.3254 ] },
|
||||
{ "ring": 3, "number": 26, "center": [ 0.1603, -0.2999 ] },
|
||||
{ "ring": 3, "number": 27, "center": [ 0.2157, -0.2628 ] },
|
||||
{ "ring": 3, "number": 28, "center": [ 0.2628, -0.2157 ] },
|
||||
{ "ring": 3, "number": 29, "center": [ 0.2999, -0.1603 ] },
|
||||
{ "ring": 3, "number": 30, "center": [ 0.3254, -0.0987 ] },
|
||||
{ "ring": 3, "number": 31, "center": [ 0.3384, -0.0333 ] },
|
||||
{ "ring": 4, "number": 0, "center": [ 0.3772, 0.0371 ] },
|
||||
{ "ring": 4, "number": 1, "center": [ 0.3627, 0.1100 ] },
|
||||
{ "ring": 4, "number": 2, "center": [ 0.3342, 0.1787 ] },
|
||||
{ "ring": 4, "number": 3, "center": [ 0.2930, 0.2404 ] },
|
||||
{ "ring": 4, "number": 4, "center": [ 0.2404, 0.2930 ] },
|
||||
{ "ring": 4, "number": 5, "center": [ 0.1787, 0.3342 ] },
|
||||
{ "ring": 4, "number": 6, "center": [ 0.1100, 0.3627 ] },
|
||||
{ "ring": 4, "number": 7, "center": [ 0.0371, 0.3772 ] },
|
||||
{ "ring": 4, "number": 8, "center": [ -0.0371, 0.3772 ] },
|
||||
{ "ring": 4, "number": 9, "center": [ -0.1100, 0.3627 ] },
|
||||
{ "ring": 4, "number": 10, "center": [ -0.1787, 0.3342 ] },
|
||||
{ "ring": 4, "number": 11, "center": [ -0.2404, 0.2930 ] },
|
||||
{ "ring": 4, "number": 12, "center": [ -0.2930, 0.2404 ] },
|
||||
{ "ring": 4, "number": 13, "center": [ -0.3342, 0.1787 ] },
|
||||
{ "ring": 4, "number": 14, "center": [ -0.3627, 0.1100 ] },
|
||||
{ "ring": 4, "number": 15, "center": [ -0.3772, 0.0371 ] },
|
||||
{ "ring": 4, "number": 16, "center": [ -0.3772, -0.0371 ] },
|
||||
{ "ring": 4, "number": 17, "center": [ -0.3627, -0.1100 ] },
|
||||
{ "ring": 4, "number": 18, "center": [ -0.3342, -0.1787 ] },
|
||||
{ "ring": 4, "number": 19, "center": [ -0.2930, -0.2404 ] },
|
||||
{ "ring": 4, "number": 20, "center": [ -0.2404, -0.2930 ] },
|
||||
{ "ring": 4, "number": 21, "center": [ -0.1787, -0.3342 ] },
|
||||
{ "ring": 4, "number": 22, "center": [ -0.1100, -0.3627 ] },
|
||||
{ "ring": 4, "number": 23, "center": [ -0.0371, -0.3772 ] },
|
||||
{ "ring": 4, "number": 24, "center": [ 0.0371, -0.3772 ] },
|
||||
{ "ring": 4, "number": 25, "center": [ 0.1100, -0.3627 ] },
|
||||
{ "ring": 4, "number": 26, "center": [ 0.1787, -0.3342 ] },
|
||||
{ "ring": 4, "number": 27, "center": [ 0.2404, -0.2930 ] },
|
||||
{ "ring": 4, "number": 28, "center": [ 0.2930, -0.2404 ] },
|
||||
{ "ring": 4, "number": 29, "center": [ 0.3342, -0.1787 ] },
|
||||
{ "ring": 4, "number": 30, "center": [ 0.3627, -0.1100 ] },
|
||||
{ "ring": 4, "number": 31, "center": [ 0.3772, -0.0371 ] },
|
||||
{ "ring": 5, "number": 0, "center": [ 0.4120, 0.0406 ] },
|
||||
{ "ring": 5, "number": 1, "center": [ 0.3962, 0.1202 ] },
|
||||
{ "ring": 5, "number": 2, "center": [ 0.3651, 0.1952 ] },
|
||||
{ "ring": 5, "number": 3, "center": [ 0.3200, 0.2626 ] },
|
||||
{ "ring": 5, "number": 4, "center": [ 0.2626, 0.3200 ] },
|
||||
{ "ring": 5, "number": 5, "center": [ 0.1952, 0.3651 ] },
|
||||
{ "ring": 5, "number": 6, "center": [ 0.1202, 0.3962 ] },
|
||||
{ "ring": 5, "number": 7, "center": [ 0.0406, 0.4120 ] },
|
||||
{ "ring": 5, "number": 8, "center": [ -0.0406, 0.4120 ] },
|
||||
{ "ring": 5, "number": 9, "center": [ -0.1202, 0.3962 ] },
|
||||
{ "ring": 5, "number": 10, "center": [ -0.1952, 0.3651 ] },
|
||||
{ "ring": 5, "number": 11, "center": [ -0.2626, 0.3200 ] },
|
||||
{ "ring": 5, "number": 12, "center": [ -0.3200, 0.2626 ] },
|
||||
{ "ring": 5, "number": 13, "center": [ -0.3651, 0.1952 ] },
|
||||
{ "ring": 5, "number": 14, "center": [ -0.3962, 0.1202 ] },
|
||||
{ "ring": 5, "number": 15, "center": [ -0.4120, 0.0406 ] },
|
||||
{ "ring": 5, "number": 16, "center": [ -0.4120, -0.0406 ] },
|
||||
{ "ring": 5, "number": 17, "center": [ -0.3962, -0.1202 ] },
|
||||
{ "ring": 5, "number": 18, "center": [ -0.3651, -0.1952 ] },
|
||||
{ "ring": 5, "number": 19, "center": [ -0.3200, -0.2626 ] },
|
||||
{ "ring": 5, "number": 20, "center": [ -0.2626, -0.3200 ] },
|
||||
{ "ring": 5, "number": 21, "center": [ -0.1952, -0.3651 ] },
|
||||
{ "ring": 5, "number": 22, "center": [ -0.1202, -0.3962 ] },
|
||||
{ "ring": 5, "number": 23, "center": [ -0.0406, -0.4120 ] },
|
||||
{ "ring": 5, "number": 24, "center": [ 0.0406, -0.4120 ] },
|
||||
{ "ring": 5, "number": 25, "center": [ 0.1202, -0.3962 ] },
|
||||
{ "ring": 5, "number": 26, "center": [ 0.1952, -0.3651 ] },
|
||||
{ "ring": 5, "number": 27, "center": [ 0.2626, -0.3200 ] },
|
||||
{ "ring": 5, "number": 28, "center": [ 0.3200, -0.2626 ] },
|
||||
{ "ring": 5, "number": 29, "center": [ 0.3651, -0.1952 ] },
|
||||
{ "ring": 5, "number": 30, "center": [ 0.3962, -0.1202 ] },
|
||||
{ "ring": 5, "number": 31, "center": [ 0.4120, -0.0406 ] },
|
||||
{ "ring": 6, "number": 0, "center": [ 0.4458, 0.0439 ] },
|
||||
{ "ring": 6, "number": 1, "center": [ 0.4287, 0.1300 ] },
|
||||
{ "ring": 6, "number": 2, "center": [ 0.3951, 0.2112 ] },
|
||||
{ "ring": 6, "number": 3, "center": [ 0.3463, 0.2842 ] },
|
||||
{ "ring": 6, "number": 4, "center": [ 0.2842, 0.3463 ] },
|
||||
{ "ring": 6, "number": 5, "center": [ 0.2112, 0.3951 ] },
|
||||
{ "ring": 6, "number": 6, "center": [ 0.1300, 0.4287 ] },
|
||||
{ "ring": 6, "number": 7, "center": [ 0.0439, 0.4458 ] },
|
||||
{ "ring": 6, "number": 8, "center": [ -0.0439, 0.4458 ] },
|
||||
{ "ring": 6, "number": 9, "center": [ -0.1300, 0.4287 ] },
|
||||
{ "ring": 6, "number": 10, "center": [ -0.2112, 0.3951 ] },
|
||||
{ "ring": 6, "number": 11, "center": [ -0.2842, 0.3463 ] },
|
||||
{ "ring": 6, "number": 12, "center": [ -0.3463, 0.2842 ] },
|
||||
{ "ring": 6, "number": 13, "center": [ -0.3951, 0.2112 ] },
|
||||
{ "ring": 6, "number": 14, "center": [ -0.4287, 0.1300 ] },
|
||||
{ "ring": 6, "number": 15, "center": [ -0.4458, 0.0439 ] },
|
||||
{ "ring": 6, "number": 16, "center": [ -0.4458, -0.0439 ] },
|
||||
{ "ring": 6, "number": 17, "center": [ -0.4287, -0.1300 ] },
|
||||
{ "ring": 6, "number": 18, "center": [ -0.3951, -0.2112 ] },
|
||||
{ "ring": 6, "number": 19, "center": [ -0.3463, -0.2842 ] },
|
||||
{ "ring": 6, "number": 20, "center": [ -0.2842, -0.3463 ] },
|
||||
{ "ring": 6, "number": 21, "center": [ -0.2112, -0.3951 ] },
|
||||
{ "ring": 6, "number": 22, "center": [ -0.1300, -0.4287 ] },
|
||||
{ "ring": 6, "number": 23, "center": [ -0.0439, -0.4458 ] },
|
||||
{ "ring": 6, "number": 24, "center": [ 0.0439, -0.4458 ] },
|
||||
{ "ring": 6, "number": 25, "center": [ 0.1300, -0.4287 ] },
|
||||
{ "ring": 6, "number": 26, "center": [ 0.2112, -0.3951 ] },
|
||||
{ "ring": 6, "number": 27, "center": [ 0.2842, -0.3463 ] },
|
||||
{ "ring": 6, "number": 28, "center": [ 0.3463, -0.2842 ] },
|
||||
{ "ring": 6, "number": 29, "center": [ 0.3951, -0.2112 ] },
|
||||
{ "ring": 6, "number": 30, "center": [ 0.4287, -0.1300 ] },
|
||||
{ "ring": 6, "number": 31, "center": [ 0.4458, -0.0439 ] },
|
||||
{ "ring": 7, "number": 0, "center": [ 0.4757, 0.0469 ] },
|
||||
{ "ring": 7, "number": 1, "center": [ 0.4574, 0.1388 ] },
|
||||
{ "ring": 7, "number": 2, "center": [ 0.4216, 0.2253 ] },
|
||||
{ "ring": 7, "number": 3, "center": [ 0.3695, 0.3032 ] },
|
||||
{ "ring": 7, "number": 4, "center": [ 0.3032, 0.3695 ] },
|
||||
{ "ring": 7, "number": 5, "center": [ 0.2253, 0.4216 ] },
|
||||
{ "ring": 7, "number": 6, "center": [ 0.1388, 0.4574 ] },
|
||||
{ "ring": 7, "number": 7, "center": [ 0.0469, 0.4757 ] },
|
||||
{ "ring": 7, "number": 8, "center": [ -0.0469, 0.4757 ] },
|
||||
{ "ring": 7, "number": 9, "center": [ -0.1388, 0.4574 ] },
|
||||
{ "ring": 7, "number": 10, "center": [ -0.2253, 0.4216 ] },
|
||||
{ "ring": 7, "number": 11, "center": [ -0.3032, 0.3695 ] },
|
||||
{ "ring": 7, "number": 12, "center": [ -0.3695, 0.3032 ] },
|
||||
{ "ring": 7, "number": 13, "center": [ -0.4216, 0.2253 ] },
|
||||
{ "ring": 7, "number": 14, "center": [ -0.4574, 0.1388 ] },
|
||||
{ "ring": 7, "number": 15, "center": [ -0.4757, 0.0469 ] },
|
||||
{ "ring": 7, "number": 16, "center": [ -0.4757, -0.0469 ] },
|
||||
{ "ring": 7, "number": 17, "center": [ -0.4574, -0.1388 ] },
|
||||
{ "ring": 7, "number": 18, "center": [ -0.4216, -0.2253 ] },
|
||||
{ "ring": 7, "number": 19, "center": [ -0.3695, -0.3032 ] },
|
||||
{ "ring": 7, "number": 20, "center": [ -0.3032, -0.3695 ] },
|
||||
{ "ring": 7, "number": 21, "center": [ -0.2253, -0.4216 ] },
|
||||
{ "ring": 7, "number": 22, "center": [ -0.1388, -0.4574 ] },
|
||||
{ "ring": 7, "number": 23, "center": [ -0.0469, -0.4757 ] },
|
||||
{ "ring": 7, "number": 24, "center": [ 0.0469, -0.4757 ] },
|
||||
{ "ring": 7, "number": 25, "center": [ 0.1388, -0.4574 ] },
|
||||
{ "ring": 7, "number": 26, "center": [ 0.2253, -0.4216 ] },
|
||||
{ "ring": 7, "number": 27, "center": [ 0.3032, -0.3695 ] },
|
||||
{ "ring": 7, "number": 28, "center": [ 0.3695, -0.3032 ] },
|
||||
{ "ring": 7, "number": 29, "center": [ 0.4216, -0.2253 ] },
|
||||
{ "ring": 7, "number": 30, "center": [ 0.4574, -0.1388 ] },
|
||||
{ "ring": 7, "number": 31, "center": [ 0.4757, -0.0469 ] },
|
||||
{ "mark": 1, "number": 0, "center": [ 0.3141, -0.1301 ] },
|
||||
{ "mark": 1, "number": 1, "center": [ 0.0933, -0.4688 ] },
|
||||
]
|
||||
}
|
||||
205
mask/json.c
Normal file
205
mask/json.c
Normal file
@ -0,0 +1,205 @@
|
||||
#include <sys/mman.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#define FREE(ptr) do{free(ptr); ptr = NULL;}while(0)
|
||||
|
||||
typedef struct{
|
||||
float x0; // left border
|
||||
float y0; // lower border
|
||||
float w; // width
|
||||
float h; // height
|
||||
} BBox;
|
||||
typedef enum{
|
||||
H_SQUARE // square hole
|
||||
,H_ELLIPSE // elliptic hole
|
||||
,H_UNDEF
|
||||
} HoleType;
|
||||
typedef struct{
|
||||
BBox box; // bounding box of hole
|
||||
int type; // type, in case of round hole borders of box are tangents to hole
|
||||
} aHole;
|
||||
|
||||
aHole globHole;
|
||||
|
||||
double get_jdouble(json_object *jobj){
|
||||
enum json_type type = json_object_get_type(jobj);
|
||||
double val;
|
||||
switch(type){
|
||||
case json_type_double:
|
||||
val = json_object_get_double(jobj);
|
||||
break;
|
||||
case json_type_int:
|
||||
val = json_object_get_int(jobj);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Wrong value! Get non-number!\n");
|
||||
exit(-1);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
double *json_get_array(json_object *jobj, int *getLen){
|
||||
enum json_type type;
|
||||
json_object *jarray = jobj;
|
||||
int arraylen = json_object_array_length(jarray);
|
||||
double *arr = calloc(arraylen, sizeof(double));
|
||||
int L = 0;
|
||||
int i;
|
||||
json_object *jvalue;
|
||||
for (i=0; i< arraylen; i++){
|
||||
jvalue = json_object_array_get_idx(jarray, i);
|
||||
type = json_object_get_type(jvalue);
|
||||
if(type == json_type_array){ // nested arrays is error
|
||||
fprintf(stderr, "Invalid file format! Found nested arrays!\n");
|
||||
exit(-1);
|
||||
}
|
||||
else if (type != json_type_object){
|
||||
arr[L++] = get_jdouble(jvalue);
|
||||
}
|
||||
else{ // non-numerical data?
|
||||
fprintf(stderr, "Invalid file format! Non-numerical data in array!\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if(L == 0) FREE(arr);
|
||||
if(getLen) *getLen = L;
|
||||
return arr;
|
||||
}
|
||||
|
||||
void get_obj_params(json_object *jobj, aHole *H){
|
||||
double *arr = NULL;
|
||||
int Len;
|
||||
enum json_type type;
|
||||
if(!H){
|
||||
fprintf(stderr, "Error: NULL instead of aHole structure!\n");
|
||||
exit(-1);
|
||||
}
|
||||
memcpy(H, &globHole, sizeof(aHole)); // initialize hole by global values
|
||||
json_object *o = json_object_object_get(jobj, "shape");
|
||||
if(o){
|
||||
const char *ptr = json_object_get_string(o);
|
||||
if(strcmp(ptr, "square") == 0) H->type = H_SQUARE;
|
||||
else if(strcmp(ptr, "round") == 0 || strcmp(ptr, "ellipse") == 0 ) H->type = H_ELLIPSE;
|
||||
else H->type = H_UNDEF;
|
||||
}
|
||||
o = json_object_object_get(jobj, "radius");
|
||||
if(o){
|
||||
type = json_object_get_type(o);
|
||||
if(type == json_type_int || type == json_type_double){ // circle / square
|
||||
double R = json_object_get_double(o);
|
||||
H->box.w = H->box.h = R * 2.;
|
||||
}else if(type == json_type_array){ // ellipse / rectangle
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 2){
|
||||
fprintf(stderr, "\"radius\" array must consist of two doubles!\n");
|
||||
exit(-1);
|
||||
}
|
||||
H->box.w = arr[0] * 2.; H->box.h = arr[1] * 2.;
|
||||
FREE(arr);
|
||||
}else{
|
||||
fprintf(stderr, "\"radius\" must be a number or an array of two doubles!\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
o = json_object_object_get(jobj, "center");
|
||||
if(o){
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 2){
|
||||
fprintf(stderr, "\"center\" must contain an array of two doubles!\n");
|
||||
exit(-1);
|
||||
}
|
||||
H->box.x0 = arr[0] - H->box.w/2.;
|
||||
H->box.y0 = arr[1] - H->box.h/2.;
|
||||
FREE(arr);
|
||||
}else{
|
||||
o = json_object_object_get(jobj, "bbox");
|
||||
if(o){
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 4){
|
||||
fprintf(stderr, "\"bbox\" must contain an array of four doubles!\n");
|
||||
exit(-1);
|
||||
}
|
||||
H->box.x0 = arr[0]; H->box.y0 = arr[1]; H->box.w = arr[2]; H->box.h = arr[3];
|
||||
FREE(arr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aHole *json_parse_holesarray(json_object *jobj, int *getLen){
|
||||
enum json_type type;
|
||||
json_object *jarray = jobj;
|
||||
int arraylen = json_object_array_length(jarray), i;
|
||||
aHole *H = calloc(arraylen, sizeof(aHole));
|
||||
json_object *jvalue;
|
||||
for (i=0; i < arraylen; i++){
|
||||
jvalue = json_object_array_get_idx(jarray, i);
|
||||
type = json_object_get_type(jvalue);
|
||||
if(type == json_type_object){
|
||||
get_obj_params(jvalue, &H[i]);
|
||||
}else{
|
||||
fprintf(stderr, "Invalid holes array format!\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if(getLen) *getLen = arraylen;
|
||||
return H;
|
||||
}
|
||||
|
||||
char *gettype(aHole *H){
|
||||
char *ret;
|
||||
switch(H->type){
|
||||
case H_SQUARE:
|
||||
ret = "square";
|
||||
break;
|
||||
case H_ELLIPSE:
|
||||
ret = "ellipse";
|
||||
break;
|
||||
default:
|
||||
ret = "undefined";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
char *ptr;
|
||||
struct stat statbuf;
|
||||
enum json_type type;
|
||||
int fd, i, HolesNum;
|
||||
aHole *HolesArray;
|
||||
size_t Mlen;
|
||||
if(argc == 2){
|
||||
if ((fd = open (argv[1], O_RDONLY)) < 0) err (1, "Can't open %s for reading", argv[1]);
|
||||
if (fstat (fd, &statbuf) < 0) err (1, "Fstat error");
|
||||
Mlen = statbuf.st_size;
|
||||
if ((ptr = mmap (0, Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
|
||||
err(1, "Mmap error for input");
|
||||
}else{
|
||||
fprintf(stderr, "No file given!\n");
|
||||
exit(-1);
|
||||
}
|
||||
json_object * jobj = json_tokener_parse(ptr);
|
||||
get_obj_params(jobj, &globHole);
|
||||
json_object *o = json_object_object_get(jobj, "holes");
|
||||
if(!o){
|
||||
fprintf(stderr, "Corrupted file: no holes found!\n");
|
||||
exit(-1);
|
||||
}
|
||||
type = json_object_get_type(o);
|
||||
if(type == json_type_object){ // single hole
|
||||
HolesArray = calloc(1, sizeof(aHole));
|
||||
assert(HolesArray);
|
||||
HolesNum = 1;
|
||||
get_obj_params(o, HolesArray);
|
||||
}else{ // array of holes
|
||||
HolesArray = json_parse_holesarray(o, &HolesNum);
|
||||
}
|
||||
if(!HolesArray || HolesNum < 1){
|
||||
fprintf(stderr, "Didn't find any holes in json file!\n");
|
||||
exit(-1);
|
||||
}
|
||||
printf("Readed %d holes\n", HolesNum);
|
||||
for(i = 0; i < HolesNum; i++){
|
||||
BBox *B = &HolesArray[i].box;
|
||||
printf("Hole %d: type=%s, bbox={%g, %g, %g, %g}\n", i, gettype(&HolesArray[i]),
|
||||
B->x0, B->y0, B->w, B->h);
|
||||
}
|
||||
munmap(ptr, Mlen);
|
||||
return 0;
|
||||
}
|
||||
34
mask/make_mask.m
Normal file
34
mask/make_mask.m
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
function make_mask()
|
||||
% ÐÏÓÔÒÏÅÎÉÅ ÇÁÒÔÍÁÎÏ×ÓËÏÊ ÍÁÓËÉ
|
||||
% SS - ÒÁÚÍÅÒ ÍÁÓËÉ
|
||||
f = fopen("holes.json", "w");
|
||||
R = [175 247 295 340 379 414 448 478] * 1e-3; % ÒÁÄÉÕÓÙ ËÏÌÅÃ ÎÁ ÇÁÒÔÍÁÎÏÇÒÁÍÍÅ
|
||||
HoleR = 7.5e-3; % ÒÁÄÉÕÓ ÏÔ×ÅÒÓÔÉÊ - 7.5ÍÍ
|
||||
R0 = .6; % ÒÁÄÉÕÓ ÓÁÍÏÊ ÇÁÒÔÍÁÎÏÇÒÁÍÍÙ
|
||||
alpha0 = pi/32; % ÓÍÅÝÅÎÉÅ ÌÕÞÅÊ ÏÔÎÏÓÉÔÅÌØÎÏ ÓÅËÕÝÉÈ ÇÏÒÉÚÏÎÔÁÌÉ/×ÅÒÔÉËÁÌÉ
|
||||
Angles = [0:31] * 2 * alpha0 + alpha0; % ÕÇÌÙ, ÐÏ ËÏÔÏÒÙÍ ÒÁÓÐÏÌÁÇÁÀÔÓÑ ÌÕÞÉ
|
||||
% ÄÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÒÁÚÍÅÓÔÉÔØ ÎÁ ÍÁÓËÅ ÏËÒÕÖÎÏÓÔÉ, ÓÏÚÄÁÄÉÍ ÍÁÓËÕ
|
||||
% ÏËÒÕÖÎÏÓÔÉ: zeros(15) Ó ÅÄÉÎÉÃÁÍÉ ÔÁÍ, ÇÄÅ ÄÏÌÖÎÁ ÂÙÔØ ÄÙÒËÁ. úÁÔÅÍ
|
||||
% ÐÏÍÅÔÉÍ ÅÄÉÎÉÃÁÍÉ × mask ÔÅ ÔÏÞËÉ, ËÕÄÁ ÄÏÌÖÅÎ ÐÏÐÁÄÁÔØ ÌÅ×ÙÊ ×ÅÒÈÎÉÊ
|
||||
fprintf(f, "{\n\t\"shape\": \"round\", \"radius\": %f,\n\t\"holes\": [\n" , HoleR);
|
||||
for i = [1 : size(R,2)] % ÃÉËÌ ÐÏ ËÏÌØÃÁÍ
|
||||
x = R(i) * cos(Angles);
|
||||
y = R(i) * sin(Angles);
|
||||
%fprintf(f, "\t\t{\"ring\": %d, \"center\": [%f, %f]\n", i, x[j], y[j]]);
|
||||
printR(f, sprintf("\"ring\": %d", i-1), x, y);
|
||||
endfor
|
||||
% ÐÏÍÅÞÁÅÍ ÍÁÒËÅÒÙ
|
||||
x = R([4 8]) .* cos([-2 -7]* 2 * alpha0);
|
||||
y = R([4 8]) .* sin([-2 -7]* 2 * alpha0);
|
||||
%fprintf(f, "\t\t{\"marker\", \"center\": [%f, %f]\n", x, y);
|
||||
printR(f, sprintf("\"mark\": 1"), x, y);
|
||||
fprintf(f, "\t]\n}\n");
|
||||
fclose(f);
|
||||
endfunction
|
||||
|
||||
function printR(f, msg, x, y)
|
||||
for i = 1:size(x,2)
|
||||
fprintf(f, "\t\t{ %9s, \"number\": %2d, \"center\": [ %7.4f, %7.4f ] },\n", msg, i-1, x(i), y(i));
|
||||
endfor
|
||||
endfunction
|
||||
107
src/CMakeLists.txt
Normal file
107
src/CMakeLists.txt
Normal file
@ -0,0 +1,107 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
if(DEFINED DEBUG)
|
||||
add_definitions(-DEBUG)
|
||||
endif()
|
||||
aux_source_directory(. SOURCES)
|
||||
set(CUFILE CUDA.cu)
|
||||
set(CFLAGS -O3 -Wall -Werror -std=gnu99)
|
||||
set(LCPATH ${CMAKE_CURRENT_SOURCE_DIR}/locale/ru)
|
||||
set(PO_FILE ${LCPATH}/messages.po)
|
||||
set(MO_FILE ${LCPATH}/LC_MESSAGES/${PROJ}.mo)
|
||||
set(RU_FILE ${LCPATH}/ru.po)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
#include(FindOpenMP)
|
||||
find_package(OpenMP)
|
||||
find_package(JPEG)
|
||||
find_package(TIFF)
|
||||
find_package(PNG)
|
||||
#find_package(OpenGL REQUIRED)
|
||||
#find_package(GTK2 REQUIRED)
|
||||
pkg_check_modules(${PROJ} REQUIRED
|
||||
# gtkglext-1.0>=0.7.0
|
||||
# gtkglext-x11-1.0>=0.7.0
|
||||
cfitsio>=3.0
|
||||
json>=0.9
|
||||
# libpng>=1.5
|
||||
# fftw3>=3.2.0
|
||||
)
|
||||
if(OPENMP_FOUND)
|
||||
add_definitions(-DOMP)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
list(APPEND ${PROJ}_INCLUDE_DIRS ${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${TIFF_INCLUDE_DIR})
|
||||
list(APPEND ${PROJ}_LIBRARIES ${JPEG_LIBRARY} ${PNG_LIBRARY} ${TIFF_LIBRARY})
|
||||
add_definitions(-D_XOPEN_SOURCE=1000 -D__JPEG=${JPEG_FOUND} -D__TIFF=${TIFF_FOUND} -D__PNG=${PNG_FOUND})
|
||||
#list(APPEND ${${PROJ}_LIBRARY_DIRS} )
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -lfftw3_threads")
|
||||
#if(NOT DEFINED NO_LEPTONICA)
|
||||
# pkg_check_modules(LIBLEPT liblept)
|
||||
#endif()
|
||||
#if(NOT DEFINED NO_GSL)
|
||||
# pkg_check_modules(GSL gsl)
|
||||
#endif()
|
||||
#if(NOT DEFINED GSL_VERSION)
|
||||
# message("GSL not found, some mathematics functions wouldn't be avialable")
|
||||
#else()
|
||||
# add_definitions(-DGSL_FOUND)
|
||||
# list(APPEND ${${PROJ}_LIBRARIES} ${GSL_LIBRARIES})
|
||||
# list(APPEND ${${PROJ}_INCLUDE_DIRS} ${GSL_INCLUDE_DIRS})
|
||||
# list(APPEND ${${PROJ}_LIBRARY_DIRS} ${GSL_LIBRARY_DIRS})
|
||||
#endif()
|
||||
#if(NOT DEFINED LIBLEPT_VERSION)
|
||||
# message("Leptonica library not found, some functions wouldn't be avialable")
|
||||
#else()
|
||||
# add_definitions(-DLEPTONICA_FOUND)
|
||||
# list(APPEND ${${PROJ}_LIBRARIES} ${LIBLEPT_LIBRARIES})
|
||||
# list(APPEND ${${PROJ}_INCLUDE_DIRS} ${LIBLEPT_INCLUDE_DIRS})
|
||||
# list(APPEND ${${PROJ}_LIBRARY_DIRS} ${LIBLEPT_LIBRARY_DIRS})
|
||||
#endif()
|
||||
|
||||
include_directories(include ${${PROJ}_INCLUDE_DIRS})
|
||||
link_directories(${${PROJ}_LIBRARY_DIRS})
|
||||
add_definitions(-DPACKAGE_VERSION=\"${PROJ_VER}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
||||
-DLOCALEDIR=\"${LOCALEDIR}\" ${CFLAGS})
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(TEST ${CMAKE_BINARY_DIR}/test)
|
||||
set(TESTSRC ${CMAKE_CURRENT_SOURCE_DIR}/test/capability.cu)
|
||||
execute_process(COMMAND nvcc -lcuda ${TESTSRC} -o ${TEST})
|
||||
execute_process(COMMAND ${TEST} OUTPUT_VARIABLE CUDA_ARCH)
|
||||
message("Cuda architecture: ${CUDA_ARCH}")
|
||||
list(APPEND CUDA_NVCC_FLAGS --use_fast_math ${CUDA_ARCH})
|
||||
#-gencode arch=compute_20,code=sm_20 -gencode arch=compute_12,code=sm_12 -gencode arch=compute_13,code=sm_13)
|
||||
cuda_include_directories(include)
|
||||
cuda_add_executable(../${PROJ} ${SOURCES} ${CUFILE} ${PO_FILE} ${MO_FILE})
|
||||
target_link_libraries( ../${PROJ} ${${PROJ}_LIBRARIES} ${CUDA_curand_LIBRARY}
|
||||
#${CUDA_CUFFT_LIBRARIES}
|
||||
)
|
||||
else(CUDA_FOUND)
|
||||
add_executable(../${PROJ} ${SOURCES} ${PO_FILE} ${MO_FILE})
|
||||
target_link_libraries( ../${PROJ} ${${PROJ}_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
)
|
||||
endif(CUDA_FOUND)
|
||||
|
||||
# Installation of the program
|
||||
INSTALL(FILES ${MO_FILE} DESTINATION ${CMAKE_INSTALL_LOCALEDIR})
|
||||
INSTALL(TARGETS ../${PROJ} DESTINATION "bin")
|
||||
|
||||
#if(DEFINED DEBUG)
|
||||
find_package(Gettext REQUIRED)
|
||||
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
|
||||
if(NOT GETTEXT_XGETTEXT_EXECUTABLE OR NOT GETTEXT_MSGFMT_EXECUTABLE)
|
||||
message(FATAL_ERROR "xgettext not found")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${PO_FILE}
|
||||
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} -D ${CMAKE_CURRENT_SOURCE_DIR} --from-code=koi8-r ${SOURCES} -c -k_ -kN_ -o ${PO_FILE}
|
||||
COMMAND sed 's/charset=UTF-8/charset=koi8-r/' ${PO_FILE} | enconv > tmp && mv -f tmp ${PO_FILE}
|
||||
COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE}
|
||||
DEPENDS ${SOURCES})
|
||||
add_custom_command(
|
||||
OUTPUT ${MO_FILE}
|
||||
COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} ${RU_FILE} -o ${MO_FILE}
|
||||
DEPENDS ${RU_FILE})
|
||||
#endif(DEFINED DEBUG)
|
||||
113
src/CPU.c
Normal file
113
src/CPU.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* CPU.c - CPU variants (if possible - on OpenMP) of main functions
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define CPU_C
|
||||
#include "mkHartmann.h"
|
||||
#include "wrapper.h"
|
||||
|
||||
// RANDOM NUMBER generation block ============================================>
|
||||
static int rand_initialized = 0;
|
||||
/*
|
||||
* Fills linear array of size sz by random float numbers
|
||||
* name: fillrandarr
|
||||
* @param sz - size of array
|
||||
* @param arr - array data (allocated outside)
|
||||
* @param Amp - amplitude of array
|
||||
* @return 0 if failed
|
||||
*/
|
||||
int CPUfillrandarr(size_t sz, float *arr, float Amp){
|
||||
FNAME();
|
||||
if(!rand_initialized){
|
||||
srand48(throw_random_seed());
|
||||
rand_initialized = 1;
|
||||
}
|
||||
size_t i;
|
||||
OMP_FOR()
|
||||
for(i = 0; i < sz; i++)
|
||||
arr[i] = (float)drand48() * Amp;
|
||||
return 1;
|
||||
}
|
||||
// <===================================== end of random number generation block
|
||||
|
||||
// BICUBIC interpolation block ===============================================>
|
||||
inline float p_ta(float t, float t2, float t3,
|
||||
float a,float b,float c,float d){
|
||||
return (2*b + t*(-a+c) + t2*(2*a-5*b+4*c-d) + t3*(-a+3*b-3*c+d)) / 2.f;
|
||||
}
|
||||
|
||||
int CPUbicubic_interp(float *out, float *in,
|
||||
size_t oH, size_t oW, size_t iH, size_t iW){
|
||||
FNAME();
|
||||
float fracX = (float)(iW-1)/(oW-1), fracY = (float)(iH-1)/(oH-1);
|
||||
size_t X, Y, ym1,y1,y2, xm1,x1,x2; // pixel coordinates on output
|
||||
size_t Ym = iH - 1, Xm = iW - 1, Pcur;
|
||||
float x,y; // coordinates on output in value of input
|
||||
OMP_FOR()
|
||||
for(Y = 0; Y < oH; Y++){
|
||||
// we can't do "y+=fracY" because of possible cumulative error
|
||||
y = (float)Y * fracY;
|
||||
int y0 = floor(y);
|
||||
float pty = y - (float)y0, pty2 = pty*pty, pty3 = pty*pty2;
|
||||
ym1 = y0-1; y1 = y0 + 1; y2 = y0 + 2;
|
||||
if(y0 == 0) ym1 = 0;
|
||||
if(y1 > Ym) y1 = Ym;
|
||||
if(y2 > Ym) y2 = Ym;
|
||||
for(X = 0, Pcur = Y * oW; X < oW; X++, Pcur++){
|
||||
// we can't do "x+=fracX" because of possible cumulative error
|
||||
x = (float)X * fracX;
|
||||
int x0 = floor(x);
|
||||
float ptx = x - (float)x0, ptx2 = ptx*ptx, ptx3 = ptx*ptx2;
|
||||
xm1 = x0-1; x1 = x0 + 1; x2 = x0 + 2;
|
||||
if(x0 == 0) xm1 = 0;
|
||||
if(x1 > Xm) x1 = Xm;
|
||||
if(x2 > Xm) x2 = Xm;
|
||||
#define TEX(x,y) (in[iW*y + x])
|
||||
#define TX(y) p_ta(ptx, ptx2, ptx3, TEX(xm1,y), \
|
||||
TEX(x0,y), TEX(x1,y), TEX(x2,y))
|
||||
out[Pcur] = p_ta(
|
||||
pty, pty2, pty3,
|
||||
TX(ym1), TX(y0), TX(y1), TX(y2));
|
||||
#undef TX
|
||||
#undef TEX
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
// <========================================= end of BICUBIC interpolation block
|
||||
|
||||
int CPUmkmirDeviat(float *map _U_, size_t mapWH _U_, float mirSZ _U_,
|
||||
mirDeviations * mirDev _U_){
|
||||
FNAME();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CPUgetPhotonXY(float *xout _U_, float *yout _U_, int R _U_ ,mirDeviations *D _U_,
|
||||
mirPar *mirParms _U_, size_t N_photons _U_, BBox *box _U_){
|
||||
FNAME();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int CPUfillImage(float *phX _U_, float *phY _U_, size_t ph_sz _U_,
|
||||
float *image _U_, size_t imW _U_, size_t imH _U_, BBox *imbox _U_){
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
807
src/CUDA.cu
Normal file
807
src/CUDA.cu
Normal file
@ -0,0 +1,807 @@
|
||||
/*
|
||||
* CUDA.cu - subroutines for GPU
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
#include <cuda.h>
|
||||
#include <curand.h>
|
||||
#include <cufft.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include "cutil_math.h"
|
||||
|
||||
|
||||
//#include <cuda_runtime_api.h>
|
||||
//#include <crt/device_runtime.h>
|
||||
//#include <device_functions.h>
|
||||
|
||||
#define EXTERN extern "C"
|
||||
#define CUDA_CU
|
||||
#include "mkHartmann.h"
|
||||
#include "wrapper.h"
|
||||
|
||||
int SHMEMSZ = 16383; // default constants, changed runtime
|
||||
int QBLKSZ = 16; // QBLKSZ = sqrt(LBLKSZ)
|
||||
int LBLKSZ = 512;
|
||||
|
||||
cudaError_t CUerr;
|
||||
inline int CUERROR(char *str){
|
||||
if(CUerr != cudaSuccess){
|
||||
WARN("%s, %s", str, cudaGetErrorString(CUerr));
|
||||
return 1;
|
||||
}else return 0;
|
||||
}
|
||||
|
||||
// Default error macro (return fail)
|
||||
#define RETMACRO do{return 0;} while(0)
|
||||
/*
|
||||
* memory macros
|
||||
*
|
||||
* Each function using them must return an int type:
|
||||
* 1 - in case of success
|
||||
* 0 - in case of fail
|
||||
*
|
||||
* Function that use them should check this status and if fails,
|
||||
* call CPU-based function for same computations
|
||||
*/
|
||||
static int ret;
|
||||
/*
|
||||
* this macro is for functions with alloc
|
||||
* All functions should in their beginning call "ret = 1;"
|
||||
* and in the end they should have a label "free_all:" after which
|
||||
* located memory free operators
|
||||
* in the end of functions should be "return ret;"
|
||||
*/
|
||||
#define FREERETMACRO do{ret = 0; goto free_all;} while(0)
|
||||
|
||||
#define CUALLOC(var, size) do{ \
|
||||
CUerr = cudaMalloc((void**)&var, size); \
|
||||
if(CUERROR("CUDA: can't allocate memory")){ \
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUALLOCPITCH(var, p, W, H) do{ \
|
||||
CUerr = cudaMallocPitch((void**)&var, p, W, H);\
|
||||
if(CUERROR("CUDA: can't allocate memory")){ \
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUMOV2DEV(dest, src, size) do{ \
|
||||
CUerr = cudaMemcpy(dest, src, size, \
|
||||
cudaMemcpyHostToDevice); \
|
||||
if(CUERROR("CUDA: can't copy data to device")){\
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUMOV2DEVPITCH(dst, dp, src, w, h) do{ \
|
||||
CUerr = cudaMemcpy2D(dst, dp, src, w, w, h,\
|
||||
cudaMemcpyHostToDevice); \
|
||||
if(CUERROR("CUDA: can't copy data to device")){\
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUMOV2HOST(dest, src, size) do{ \
|
||||
CUerr = cudaMemcpy(dest, src, size, \
|
||||
cudaMemcpyDeviceToHost); \
|
||||
if(CUERROR("CUDA: can't copy data to host")){\
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUMOV2HOSTPITCH(dst,src,spitch,w,h) do{ \
|
||||
CUerr = cudaMemcpy2D(dst,w,src,spitch,w,h, \
|
||||
cudaMemcpyDeviceToHost); \
|
||||
if(CUERROR("CUDA: can't copy data to device")){\
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
#define CUFREE(var) do{cudaFree(var); var = NULL; }while(0)
|
||||
#define CUFFTCALL(fn) do{ \
|
||||
cufftResult fres = fn; \
|
||||
if(CUFFT_SUCCESS != fres){ \
|
||||
WARN("CUDA fft error %d", fres); \
|
||||
FREERETMACRO; \
|
||||
}}while(0)
|
||||
|
||||
texture<float, 2> cuTex;//1, cuTex2, cuTex3;
|
||||
#define CUTEXTURE(t, data, W, H, pitch) do{ \
|
||||
CUerr = cudaBindTexture2D(NULL, t, \
|
||||
data, W, H, pitch); \
|
||||
if(CUERROR("CUDA: can't bind texture")){ \
|
||||
FREERETMACRO;}else{ \
|
||||
t.addressMode[0] = cudaAddressModeClamp; \
|
||||
t.addressMode[1] = cudaAddressModeClamp; \
|
||||
t.normalized = false; \
|
||||
t.filterMode = cudaFilterModePoint; \
|
||||
}}while(0)
|
||||
|
||||
//#define _TEXTURE_(N, ...) CUTEXTURE(cuTex ## N, __VA_ARGS__)
|
||||
//#define TEXDATA(...) _TEXTURE_(__VA_ARGS__)
|
||||
//#define TEXTURE(N) cuTex ## N
|
||||
#define TEXDATA(...) CUTEXTURE(cuTex, __VA_ARGS__)
|
||||
#define TEXTURE() cuTex
|
||||
|
||||
/**
|
||||
* getting the videocard parameters
|
||||
* @return 0 if check failed
|
||||
*/
|
||||
EXTERN int CUgetprops(){
|
||||
cudaDeviceProp dP;
|
||||
CUdevice dev;
|
||||
CUcontext ctx;
|
||||
if(cudaSuccess != cudaGetDeviceProperties(&dP, 0)) return 0;
|
||||
if(CUDA_SUCCESS != cuDeviceGet(&dev,0)) return 0;
|
||||
// create context for program run:
|
||||
if(CUDA_SUCCESS != cuCtxCreate(&ctx, 0, dev)) return 0;
|
||||
printf("\nDevice: %s, totalMem=%zd, memPerBlk=%zd,\n", dP.name, dP.totalGlobalMem, dP.sharedMemPerBlock);
|
||||
printf("warpSZ=%d, TPB=%d, TBDim=%dx%dx%d\n", dP.warpSize, dP.maxThreadsPerBlock,
|
||||
dP.maxThreadsDim[0],dP.maxThreadsDim[1],dP.maxThreadsDim[2]);
|
||||
printf("GridSz=%dx%dx%d, MemovrLap=%d, GPUs=%d\n", dP.maxGridSize[0],
|
||||
dP.maxGridSize[1],dP.maxGridSize[2],
|
||||
dP.deviceOverlap, dP.multiProcessorCount);
|
||||
printf("canMAPhostMEM=%d\n", dP.canMapHostMemory);
|
||||
printf("compute capability");
|
||||
green(" %d.%d.\n\n", dP.major, dP.minor);
|
||||
if(dP.major > 1){
|
||||
SHMEMSZ = 49151; QBLKSZ = 32; LBLKSZ = 1024;
|
||||
}
|
||||
// cuCtxDetach(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether there is enough memory
|
||||
* @param memsz - memory needed
|
||||
* @param Free - free memory (maybe NULL if not needed)
|
||||
* @param Total - total memory (maybe NULL if not needed)
|
||||
* @return 0 if check failed
|
||||
*/
|
||||
EXTERN int CUgetMEM(size_t memsz, size_t *Free, size_t *Total){
|
||||
size_t theFree = 0, theTotal = 0;
|
||||
if(CUDA_SUCCESS != cuMemGetInfo( &theFree, &theTotal )) return 0;
|
||||
if(Free) *Free = theFree;
|
||||
if(Total) *Total = theTotal;
|
||||
if(theFree < memsz) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
size_t theFree, theTotal;
|
||||
CUgetMEM(0, &theFree, &theTotal);
|
||||
printf(_("MEMORY: free = "));
|
||||
green("%zdMB,", theFree / MB);
|
||||
printf(_(" total= "));
|
||||
green("%zdMB\n", theTotal / MB);
|
||||
*/
|
||||
|
||||
/**
|
||||
* Memory allocation & initialisation test
|
||||
* @param memsz - wanted memory to allocate
|
||||
* @return 0 if check failed
|
||||
*/
|
||||
EXTERN int CUallocaTest(size_t memsz){
|
||||
char *mem;
|
||||
ret = 1;
|
||||
printf("cudaMalloc(char, %zd)\n", memsz);
|
||||
CUALLOC(mem, memsz);
|
||||
if(cudaSuccess != cudaMemset(mem, 0xaa, memsz)) ret = 0;
|
||||
free_all:
|
||||
CUFREE(mem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* RANDOM NUMBER generation block ============================================>
|
||||
*
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Possible functions:
|
||||
* curandGenerateUniform(curandGenerator_t generator, float *outputPtr, size_t num)
|
||||
* curandGenerateNormal(curandGenerator_t generator, float *outputPtr, size_t n, float mean, float stddev)
|
||||
* curandGenerateLogNormal(curandGenerator_t generator, float *outputPtr, size_t n, float mean, float stddev)
|
||||
* curandGeneratePoisson(curandGenerator_t generator, unsigned int *outputPtr, size_t n, double lambda)
|
||||
*/
|
||||
#define CURAND_CALL(x) do { \
|
||||
curandStatus_t st = x; \
|
||||
if(st!=CURAND_STATUS_SUCCESS) { \
|
||||
WARN("CURAND error %d", st); \
|
||||
FREERETMACRO; \
|
||||
}} while(0)
|
||||
|
||||
|
||||
__global__ void multiply_rand(float *arr, size_t sz, float Amp){
|
||||
size_t IDX = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(IDX >= sz) return;
|
||||
arr[IDX] *= Amp;
|
||||
}
|
||||
static int rand_initialized = 0;
|
||||
static curandGenerator_t gen;
|
||||
/**
|
||||
* Fills linear array of size sz by random float numbers
|
||||
* @param sz - size of array
|
||||
* @param arr - array data (allocated outside)
|
||||
* @param Amp - amplitude of array
|
||||
* @return 0 if failed
|
||||
*/
|
||||
EXTERN int CUfillrandarr(size_t sz, float *arr, float Amp){
|
||||
FNAME();
|
||||
ret = 1;
|
||||
float *devmem;
|
||||
if(!rand_initialized){
|
||||
CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
|
||||
CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, throw_random_seed()));
|
||||
rand_initialized = 1;
|
||||
}
|
||||
CUALLOC(devmem, sz*sizeof(float));
|
||||
CURAND_CALL(curandGenerateUniform(gen, devmem, sz));
|
||||
cudaThreadSynchronize();
|
||||
if(fabs(Amp < 1.f) > FLT_EPSILON){
|
||||
size_t dimens = (sz + LBLKSZ - 1) / LBLKSZ;
|
||||
multiply_rand<<<dimens, LBLKSZ>>>(devmem, sz, Amp);
|
||||
cudaThreadSynchronize();
|
||||
}
|
||||
CUMOV2HOST(arr, devmem, sz*sizeof(float));
|
||||
free_all:
|
||||
//CURAND_CALL(curandDestroyGenerator(gen));
|
||||
CUFREE(devmem);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
* <===================================== end of random number generation block
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* BICUBIC interpolation block ===============================================>
|
||||
*
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* matrix operation:
|
||||
*
|
||||
* p(t, a, b, c, d) =
|
||||
* / 0 2 0 0 \ / a \
|
||||
* = 1/2 ( 1 t t^2 t^3 ) * | -1 0 1 0 | * | b |
|
||||
* | 2 -5 4 -1 | | c |
|
||||
* \ -1 3 -3 1 / \ d /
|
||||
*/
|
||||
inline __device__ float p_ta(float t, float t2, float t3,
|
||||
float a,float b,float c,float d){
|
||||
return (2*b + t*(-a+c) + t2*(2*a-5*b+4*c-d) + t3*(-a+3*b-3*c+d)) / 2.f;
|
||||
}
|
||||
// bicubic interpolation of texture in point with coordinates (x, y)
|
||||
__device__ float interpolate_bicubic(float x, float y){
|
||||
#define TEX(X,Y) tex2D(TEXTURE(), X, y0+(Y))
|
||||
#define TX(Y) p_ta(pt.x, pt2.x, pt3.x, TEX(x0-1,Y), \
|
||||
TEX(x0,Y), TEX(x0+1,Y), TEX(x0+2,Y))
|
||||
float2 crd = make_float2(x,y);
|
||||
float2 zeropt = floor(crd);
|
||||
float2 pt = crd - zeropt;
|
||||
float2 pt2 = pt*pt;
|
||||
float2 pt3 = pt*pt2;
|
||||
float x0 = zeropt.x, y0 = zeropt.y;
|
||||
//return x;
|
||||
return p_ta(
|
||||
pt.y, pt2.y, pt3.y,
|
||||
TX(-1), TX(0), TX(1), TX(2)
|
||||
);
|
||||
#undef TEX
|
||||
#undef TX
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate base coordinates for new image in point (X,Y) relative to old image
|
||||
* @param out - new image data
|
||||
* @param fracX, fracY - scale of new image pixel relative to old image
|
||||
* @parami oW, oH - new image dimensions
|
||||
*/
|
||||
__global__ void bicubic_interp(float *out,
|
||||
float fracX, float fracY,
|
||||
unsigned int oW, unsigned int oH){
|
||||
int X, Y; // pixel coordinates on output
|
||||
float x,y; // coordinates on output in value of input
|
||||
X = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
Y = threadIdx.y + blockDim.y * blockIdx.y;
|
||||
if(X >= oW || Y >= oH) return;
|
||||
x = (float)X * fracX;
|
||||
y = (float)Y * fracY;
|
||||
out[Y*oW+X] = interpolate_bicubic(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolation of image by bicubic splines
|
||||
* @param out_dev - new image data in device memory
|
||||
* @param in - old image data
|
||||
* @param oH, oW - new image size
|
||||
* @param iH, iW - old image size
|
||||
* @return 0 if fails
|
||||
*/
|
||||
EXTERN int CUbicubic_interpDEV(float **out_dev, float *in,
|
||||
size_t oH, size_t oW, size_t iH, size_t iW){
|
||||
FNAME();
|
||||
size_t iWp = iW*sizeof(float), oSz = oH*oW*sizeof(float), pitch;
|
||||
float *in_dev = NULL;
|
||||
ret = 1;
|
||||
dim3 blkdim(QBLKSZ, QBLKSZ);
|
||||
dim3 griddim((oW+QBLKSZ-1)/QBLKSZ, (oH+QBLKSZ-1)/QBLKSZ);
|
||||
CUALLOCPITCH(in_dev, &pitch, iWp, iH);
|
||||
CUMOV2DEVPITCH(in_dev, pitch, in, iWp, iH);
|
||||
CUALLOC(*out_dev, oSz);
|
||||
TEXDATA(in_dev, iW, iH, pitch);
|
||||
bicubic_interp<<<griddim, blkdim>>>(*out_dev,
|
||||
(float)(iW-1)/(oW-1), (float)(iH-1)/(oH-1), oW, oH);
|
||||
cudaThreadSynchronize();
|
||||
free_all:
|
||||
cudaUnbindTexture(TEXTURE());
|
||||
CUFREE(in_dev);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Interpolation of image by bicubic splines
|
||||
* @param out, in - new and old images data
|
||||
* @param oH, oW - new image size
|
||||
* @param iH, iW - old image size
|
||||
* @return 0 if fails
|
||||
*/
|
||||
EXTERN int CUbicubic_interp(float *out, float *in,
|
||||
size_t oH, size_t oW, size_t iH, size_t iW){
|
||||
FNAME();
|
||||
float *out_dev = NULL;
|
||||
ret = 1;
|
||||
if(!CUbicubic_interpDEV(&out_dev,in,oH,oW,iH,iW)){FREERETMACRO;}
|
||||
CUMOV2HOST(out, out_dev, oH*oW*sizeof(float));
|
||||
free_all:
|
||||
CUFREE(out_dev);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
* <========================================= end of BICUBIC interpolation block
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Begin of mirror normales block =============================================>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Compute X & Y components of "curved mirror" gradient
|
||||
* This components (interpolated) should be added to SURFACE gradient **before** normalisation
|
||||
* @param Sz - image size in both directions
|
||||
* @param mirPixSZ - pixel size in meters
|
||||
* @param dZdX, dZdY - addition gradient components
|
||||
*
|
||||
*
|
||||
* Normale of "curved mirror" computes so:
|
||||
* N1 = -i*x/2f -j*y/2f + k ==> direction vector of ideal mirror
|
||||
* dN ==> bicubic interpolation of gradient matrix of mirror surface deviations
|
||||
* dN = i*dX + j*dY
|
||||
* N = N1 + dN ==> "real" direction vector
|
||||
* |N| = length(N) ==> its length
|
||||
* n = N / |N| ==> normale to "real" mirror surface
|
||||
* the normale n can be transformed due to mirror inclination and displation
|
||||
*
|
||||
* Let f be a direction vector of falling photon, then a=[-2*dot(f,n)*n]
|
||||
* will be a twice projection of f to n with "-" sign (dot(x,y) == scalar product)
|
||||
* reflected direction vector will be
|
||||
* r = a + f ==>
|
||||
* r = f - 2*dot(f,n)*n
|
||||
* r doesn't need normalisation
|
||||
*
|
||||
* If (x0,y0,z0) is mirror surface coordinates, z0 = z(x,y) + dZ, wehere dZ interpolated;
|
||||
* then image coordinates on plane z=Zx would be:
|
||||
* X = x0 + k*rx, Y = y0 + k*ry, k = (Zx - z0) / rz.
|
||||
*
|
||||
* First check point on a mask plane; if photon falls to a hole in mask, increment
|
||||
* value on corresponding image pixel
|
||||
*/
|
||||
// 1./sqrt(2)
|
||||
#define DIVSQ2 0.7071068f
|
||||
// 2*(1+2/sqrt(2))
|
||||
#define WEIGHT 482.842712f
|
||||
__global__ void calcMir_dXdY(size_t Sz, float mirPixSZ,
|
||||
float *dZdX, float *dZdY){
|
||||
#define TEX(X,Y) tex2D(TEXTURE(), X0+(X), Y0+(Y))*100.f
|
||||
#define PAIR(X,Y) (TEX((X),(Y))-TEX(-(X),-(Y)))
|
||||
int X0,Y0;
|
||||
X0 = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
Y0 = threadIdx.y + blockDim.y * blockIdx.y;
|
||||
// check if we are inside image
|
||||
if(X0 >= Sz || Y0 >= Sz) return;
|
||||
// calculate gradient components
|
||||
int idx = Y0 * Sz + X0;
|
||||
mirPixSZ *= WEIGHT;
|
||||
dZdX[idx] = (PAIR(1,0) + DIVSQ2*(PAIR(1,-1)+PAIR(1,1)))/mirPixSZ;
|
||||
// REMEMBER!!! Axe Y looks up, so we must change the sign
|
||||
dZdY[idx] = -(PAIR(0,1) + DIVSQ2*(PAIR(1,1)+PAIR(-1,1)))/mirPixSZ;
|
||||
#undef PAIR
|
||||
#undef TEX
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute matrices of mirror surface deviation
|
||||
* @param map, mapWH - square matrix of surface deviations (in meters) and its size
|
||||
* @param mirDia - mirror diameter
|
||||
* @param mirWH - size of output square matrices (mirWH x mirWH)
|
||||
* @param mirZ - matrix of mirror Z variations (add to mirror Z)
|
||||
* @param mirDX, mirDY - partial derivatives dZ/dx & dZ/dy (add to mirror der.)
|
||||
* @return 0 if fails
|
||||
*/
|
||||
EXTERN int CUmkmirDeviat(float *map, size_t mapWH, float mirDia,
|
||||
mirDeviations * mirDev){
|
||||
FNAME();
|
||||
ret = 1;
|
||||
size_t mirWH = mirDev->mirWH;
|
||||
float *mirDXd = NULL, *mirDYd = NULL, *mirZd = NULL;
|
||||
size_t mirSp = mirWH*sizeof(float);
|
||||
size_t mirSz = mirWH*mirSp, dimens = (mirWH+QBLKSZ-1)/QBLKSZ;
|
||||
size_t pitch;
|
||||
dim3 blkdim(QBLKSZ, QBLKSZ);
|
||||
dim3 griddim(dimens, dimens);
|
||||
// make Z -- simple approximation of
|
||||
if(!CUbicubic_interpDEV(&mirZd,map,mirWH,mirWH,mapWH,mapWH)){FREERETMACRO;}
|
||||
CUMOV2HOST(mirDev->mirZ, mirZd, mirSz);
|
||||
CUFREE(mirZd);
|
||||
// Z-data would be in pitched 2D array for texture operations
|
||||
// (to simplify "stretching")
|
||||
CUALLOCPITCH(mirZd, &pitch, mirSp, mirWH);
|
||||
CUMOV2DEVPITCH(mirZd, pitch, mirDev->mirZ, mirSp, mirWH);
|
||||
TEXDATA(mirZd, mirWH, mirWH, pitch);
|
||||
|
||||
CUALLOC(mirDXd, mirSz);
|
||||
CUALLOC(mirDYd, mirSz);
|
||||
calcMir_dXdY<<<griddim, blkdim>>>(mirWH, mirDia/((float)(mirWH-1)), mirDXd, mirDYd);
|
||||
cudaThreadSynchronize();
|
||||
CUMOV2HOST(mirDev->mirDX, mirDXd, mirSz);
|
||||
CUMOV2HOST(mirDev->mirDY, mirDYd, mirSz);
|
||||
free_all:
|
||||
cudaUnbindTexture(TEXTURE());
|
||||
CUFREE(mirDXd);
|
||||
CUFREE(mirDYd);
|
||||
CUFREE(mirZd);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
* <============================================== end of mirror normales block
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* Photons trace block ========================================================>
|
||||
*
|
||||
*
|
||||
*/
|
||||
typedef struct{
|
||||
float3 l1;
|
||||
float3 l2;
|
||||
float3 l3;
|
||||
}Matrix;
|
||||
|
||||
// rotation of vec on rotation matrix with lines rM1, rM2, rM3
|
||||
__inline__ __device__ float3 rotZA(Matrix *M, float3 vec){
|
||||
return make_float3(dot(M->l1,vec), dot(M->l2,vec), dot(M->l3, vec));
|
||||
}
|
||||
|
||||
// textures for linear interpolation of mirror deviations
|
||||
texture<float, 2> TZ;
|
||||
texture<float, 2> TdX;
|
||||
texture<float, 2> TdY;
|
||||
// struct for reducing parameters amount
|
||||
typedef struct{
|
||||
Matrix M;
|
||||
mirPar P;
|
||||
BBox B;
|
||||
bool rot;
|
||||
Diaphragm D;
|
||||
}MPB;
|
||||
/**
|
||||
* Calculate reflected photon coordinates at plane Z0
|
||||
* @param photonX, photonY **INOUT** -
|
||||
* out: arrays with photon coordinates on image plane
|
||||
* in: coordinates in diapazone [0,1)
|
||||
* @param photonSZ - size of prevoius arrays
|
||||
* @param Z0 - Z-coordinate of image plane
|
||||
* @param M - mirror rotation matrix or NULL if rotation is absent
|
||||
* @param mir_WH - mirror derivations matrix size
|
||||
* @param Parms - mirror parameters
|
||||
* @param f - light direction vector
|
||||
*
|
||||
* @param holes - array with
|
||||
*/
|
||||
__global__ void getXY(float *photonX, float *photonY, size_t photonSZ,
|
||||
float Z0, MPB *mpb, size_t mir_WH, float3 f){
|
||||
#define BADPHOTON() do{photonX[IDX] = 1e10f; photonY[IDX] = 1e10f; return;}while(0)
|
||||
size_t IDX; // pixel number in array
|
||||
IDX = threadIdx.x + blockDim.x * blockIdx.x;
|
||||
if(IDX >= photonSZ) return;
|
||||
Matrix *M = &mpb->M;
|
||||
mirPar *Parms = &mpb->P;
|
||||
BBox *box = &mpb->B;
|
||||
float _2F = Parms->F * 2.f, R = Parms->D / 2.f;
|
||||
float x,y,z; // coordinates on mirror in meters
|
||||
x = box->x0 + photonX[IDX] * box->w; // coords of photons
|
||||
y = box->y0 + photonY[IDX] * box->h;
|
||||
float r2 = x*x + y*y;
|
||||
z = r2 / _2F / 2.f;
|
||||
// we don't mean large inclination so check border by non-inclinated mirror
|
||||
if(r2 > R*R) BADPHOTON();
|
||||
float pixSZ = Parms->D / float(mir_WH-1); // "pixel" size on mirror
|
||||
// coordinates on deviation matrix, don't forget about y-mirroring!
|
||||
float xOnMat = (x + R) / pixSZ, yOnMat = (R - y) / pixSZ;
|
||||
// now add z-deviations, linear interpolation of pre-computed matrix
|
||||
z += tex2D(TZ, xOnMat, yOnMat);
|
||||
// point on unrotated mirror
|
||||
float3 point = make_float3(x,y,z);
|
||||
// compute normals to unrotated mirror
|
||||
float3 normal = make_float3( tex2D(TdX, xOnMat, yOnMat) - x/_2F,
|
||||
tex2D(TdY, xOnMat, yOnMat) - y/_2F,
|
||||
1.f
|
||||
);
|
||||
// rotate mirror
|
||||
if(mpb->rot){
|
||||
point = rotZA(M, point);
|
||||
normal = rotZA(M, normal);
|
||||
}
|
||||
normal = normalize(normal);
|
||||
// calculate reflection direction vector
|
||||
float3 refl = 2.f*fabs(dot(f, normal))*normal + f;
|
||||
float K;
|
||||
if(mpb->D.Nholes){ // there is a diaphragm - test it
|
||||
Diaphragm *D = &(mpb->D);
|
||||
int S = D->mask->WH; // size of diaphragm matrix
|
||||
K = (D->Z - point.z) / refl.z; // scale to convert normal to vector
|
||||
float xleft = D->box.x0, ybot = D->box.y0; // left bottom angle of dia box
|
||||
float scalex = D->box.w/(float)S, scaley = D->box.h/(float)S;
|
||||
x = point.x + K*refl.x;
|
||||
y = point.y + K*refl.y;
|
||||
int curX = (int)((x - xleft) / scalex + 0.5f); // coords on dia matrix
|
||||
int curY = (int)((y - ybot) / scaley + 0.5f);
|
||||
if(curX < 0 || curX >= S || curY < 0 || curY >= S) BADPHOTON();
|
||||
uint16_t mark = D->mask->data[curY*S + curX];
|
||||
if(!mark) BADPHOTON();
|
||||
do{
|
||||
int t = D->holes[mark-1].type;
|
||||
BBox *b = &D->holes[mark-1].box;
|
||||
float rx = b->w/2.f, ry = b->h/2.f;
|
||||
float xc = b->x0 + rx, yc=b->y0 + ry;
|
||||
float sx = x - xc, sy = y - yc;
|
||||
switch(t){
|
||||
case H_SQUARE:
|
||||
if(fabs(sx) > rx || fabs(sy) > ry) mark = 0;
|
||||
break;
|
||||
case H_ELLIPSE:
|
||||
if(sx*sx/rx/rx+sy*sy/ry/ry > 1.f) mark = 0;
|
||||
break;
|
||||
default:
|
||||
mark = 0;
|
||||
}
|
||||
}while(0);
|
||||
if(!mark) BADPHOTON();
|
||||
}
|
||||
// OK, test is passed, calculate position on Z0:
|
||||
K = (Z0 - point.z) / refl.z;
|
||||
x = point.x + K*refl.x;
|
||||
y = point.y + K*refl.y;
|
||||
photonX[IDX] = x;
|
||||
photonY[IDX] = y;
|
||||
#undef BADPHOTON
|
||||
}
|
||||
|
||||
/**
|
||||
* get coordinates of photons falling onto mirror at point X,Y, reflected
|
||||
* to plane with z=mirParms->foc
|
||||
*
|
||||
* @param xout, yout - arrays of size N_photons with coordinates (allocated outside)
|
||||
* @param R - use photon coordinates from xout, yout or generate random (in interval [0,1))
|
||||
* @param D - deviation & its derivative matrices
|
||||
* @param mirParms - parameters of mirror
|
||||
* @param N_photons - number of photons for output (not more than size of input!)
|
||||
* @param box - bbox where photons are falling
|
||||
* @return 0 if failed
|
||||
*/
|
||||
EXTERN int CUgetPhotonXY(float *xout, float *yout, int R, mirDeviations *D,
|
||||
mirPar *mirParms, size_t N_photons, BBox *box){
|
||||
//FNAME();
|
||||
ret = 1;
|
||||
MPB *mpbdev = NULL, mpb;
|
||||
aHole *hdev = NULL;
|
||||
mirMask *mmdev = NULL;
|
||||
uint16_t *mdatadev = NULL;
|
||||
float *X = NULL, *Y = NULL;
|
||||
float SZ = sin(mirParms->objZ);
|
||||
float z = mirParms->foc;
|
||||
float *Z_dev = NULL, *dX_dev = NULL, *dY_dev = NULL;
|
||||
float A = mirParms->Aincl, Z = mirParms->Zincl;
|
||||
size_t H = D->mirWH, Wp = H*sizeof(float), pitch;
|
||||
float cA = cos(A), sA = sin(A), cZ = cos(Z), sZ = sin(Z);
|
||||
size_t sz = N_photons * sizeof(float);
|
||||
size_t dimens = (N_photons+LBLKSZ-1)/LBLKSZ;
|
||||
// light direction vector
|
||||
float3 f = make_float3(-SZ*sin(mirParms->objA), -SZ*cos(mirParms->objA), -cos(mirParms->objZ));
|
||||
// rotation matrix by Z than by A:
|
||||
Matrix M, *Mptr = NULL;
|
||||
if(A != 0.f || Z != 0.f){
|
||||
M.l1 = make_float3(cA, sA*cZ, sA*sZ);
|
||||
M.l2 = make_float3(-sA, cA*cZ, cA*sZ);
|
||||
M.l3 = make_float3(0.f, -sZ, cZ);
|
||||
Mptr = &M;
|
||||
}
|
||||
// textures for linear interpolation
|
||||
CUALLOCPITCH(Z_dev, &pitch, Wp, H);
|
||||
CUALLOCPITCH(dX_dev, &pitch, Wp, H);
|
||||
CUALLOCPITCH(dY_dev, &pitch, Wp, H);
|
||||
CUMOV2DEVPITCH(Z_dev, pitch, D->mirZ, Wp, H);
|
||||
CUMOV2DEVPITCH(dX_dev, pitch, D->mirDX, Wp, H);
|
||||
CUMOV2DEVPITCH(dY_dev, pitch, D->mirDY, Wp, H);
|
||||
#define CUTEX(tex, var) CUTEXTURE(tex, var, H, H, pitch); tex.filterMode = cudaFilterModeLinear
|
||||
CUTEX(TZ, Z_dev);
|
||||
CUTEX(TdX, dX_dev);
|
||||
CUTEX(TdY, dY_dev);
|
||||
#undef CUTEX
|
||||
CUALLOC(X, sz);
|
||||
CUALLOC(Y, sz);
|
||||
if(R){
|
||||
// create __device__ random arrays X & Y
|
||||
if(!rand_initialized){
|
||||
CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
|
||||
CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, throw_random_seed()));
|
||||
rand_initialized = 1;
|
||||
}
|
||||
CURAND_CALL(curandGenerateUniform(gen, X, N_photons));
|
||||
cudaThreadSynchronize();
|
||||
CURAND_CALL(curandGenerateUniform(gen, Y, N_photons));
|
||||
cudaThreadSynchronize();
|
||||
}else{
|
||||
// move xout, yout to X,Y
|
||||
CUMOV2DEV(X, xout, sz);
|
||||
CUMOV2DEV(Y, yout, sz);
|
||||
}
|
||||
CUALLOC(mpbdev, sizeof(MPB));
|
||||
if(Mptr){
|
||||
mpb.rot = true;
|
||||
memcpy(&mpb.M, Mptr, sizeof(Matrix));
|
||||
}else{
|
||||
mpb.rot = false;
|
||||
}
|
||||
memcpy(&mpb.P, mirParms, sizeof(mirPar));
|
||||
memcpy(&mpb.B, box, sizeof(BBox));
|
||||
if(!mirParms->dia) mpb.D.Nholes = 0;
|
||||
// initialize diaphragm
|
||||
if(mirParms->dia){ // diaphragm is present - allocate memory for it
|
||||
Diaphragm tmpd;
|
||||
mirMask tmpM;
|
||||
memcpy(&tmpd, mirParms->dia, sizeof(Diaphragm));
|
||||
memcpy(&tmpM, mirParms->dia->mask, sizeof(mirMask));
|
||||
size_t S = sizeof(aHole) * mirParms->dia->Nholes;
|
||||
CUALLOC(hdev, S);
|
||||
CUMOV2DEV(hdev, mirParms->dia->holes, S);
|
||||
tmpd.holes = hdev;
|
||||
S = mirParms->dia->mask->WH;
|
||||
S = sizeof(uint16_t) * S * S;
|
||||
CUALLOC(mdatadev, S);
|
||||
CUMOV2DEV(mdatadev, mirParms->dia->mask->data, S);
|
||||
tmpM.data = mdatadev;
|
||||
CUALLOC(mmdev, sizeof(mirMask));
|
||||
CUMOV2DEV(mmdev, &tmpM, sizeof(mirMask));
|
||||
tmpd.mask = mmdev;
|
||||
memcpy(&mpb.D, &tmpd, sizeof(Diaphragm));
|
||||
}
|
||||
CUMOV2DEV(mpbdev, &mpb, sizeof(MPB));
|
||||
getXY<<<dimens, LBLKSZ>>>(X, Y, N_photons, z, mpbdev, H, f);
|
||||
cudaThreadSynchronize();
|
||||
CUMOV2HOST(xout, X, sz);
|
||||
CUMOV2HOST(yout, Y, sz);
|
||||
free_all:
|
||||
CUFREE(hdev); CUFREE(mmdev); CUFREE(mdatadev);
|
||||
//CURAND_CALL(curandDestroyGenerator(gen));
|
||||
cudaUnbindTexture(TZ);
|
||||
cudaUnbindTexture(TdX);
|
||||
cudaUnbindTexture(TdY);
|
||||
CUFREE(mpbdev);
|
||||
CUFREE(Z_dev); CUFREE(dX_dev); CUFREE(dY_dev);
|
||||
CUFREE(X); CUFREE(Y);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
*
|
||||
*
|
||||
* <================================================= end of Photons trace block
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
typedef struct{
|
||||
float x0; // (x0,y0) - left lower corner
|
||||
float y0;
|
||||
float x1; // (x1,y1) - right upper corner
|
||||
float y1;
|
||||
size_t pitch; // data pitch in array !!IN NUMBER OF ELEMENTS!!
|
||||
float dX; // pixel size, dX = (x1-x0) / [image width - 1 ]
|
||||
float dY; // pixel size, dY = (y1-y0) / [image height - 1]
|
||||
}devBox;
|
||||
|
||||
__global__ void fillimage(float *image, float *xx, float *yy, size_t sz, devBox *b){
|
||||
size_t IDX = threadIdx.x + blockDim.x * blockIdx.x, X, Y;
|
||||
if(IDX >= sz) return;
|
||||
float x = xx[IDX], y = yy[IDX];
|
||||
if(x < b->x0 || x > b->x1) return;
|
||||
if(y < b->y0 || y > b->y1) return;
|
||||
X = (size_t)((x - b->x0) / b->dX);
|
||||
Y = (size_t)((b->y1 - y) / b->dY);
|
||||
//atomicAdd(&image[Y*b->pitch + X], 1.f)
|
||||
image[Y*b->pitch + X] += 1.f;
|
||||
}*/
|
||||
/**
|
||||
*
|
||||
* @param phX, phY - photons coordinates
|
||||
* @param ph_sz - number of photons
|
||||
* @param image - resulting image (photons **adds** to it)
|
||||
* @param imW, imH - size of resulting image
|
||||
* @param imbox - bounding box of resulting image
|
||||
* @return 0 if fails
|
||||
*/
|
||||
/*
|
||||
EXTERN int CUfillImage(float *phX, float *phY, size_t ph_sz,
|
||||
float *image, size_t imW, size_t imH, BBox *imbox){
|
||||
ret = 1;
|
||||
size_t linsz = ph_sz * sizeof(float);
|
||||
size_t pitch, iWp = imW * sizeof(float);
|
||||
float *xdev = NULL, *ydev = NULL, *imdev = NULL;
|
||||
devBox *bdev = NULL, devbox;
|
||||
size_t dimens = (ph_sz+LBLKSZ-1)/LBLKSZ;
|
||||
|
||||
CUALLOC(xdev, linsz); CUALLOC(ydev, linsz);
|
||||
CUALLOC(bdev, sizeof(devBox));
|
||||
CUALLOCPITCH(imdev, &pitch, iWp, imH);
|
||||
DBG("pitch: %zd", pitch);
|
||||
CUMOV2DEVPITCH(imdev, pitch, image, iWp, imH);
|
||||
CUMOV2DEV(xdev, phX, linsz);
|
||||
CUMOV2DEV(ydev, phY, linsz);
|
||||
devbox.x0 = imbox->x0; devbox.y0 = imbox->y0;
|
||||
devbox.x1 = imbox->x0 + imbox->w;
|
||||
devbox.y1 = imbox->y0 + imbox->h;
|
||||
devbox.pitch = pitch / sizeof(float);
|
||||
devbox.dX = imbox->w / (float)(imW - 1);
|
||||
devbox.dY = imbox->h / (float)(imH - 1);
|
||||
CUMOV2DEV(bdev, &devbox, sizeof(devBox));
|
||||
fillimage<<<dimens, LBLKSZ>>>(imdev, xdev, ydev, ph_sz, bdev);
|
||||
cudaThreadSynchronize();
|
||||
CUMOV2HOSTPITCH(image, imdev, pitch, iWp, imH);
|
||||
free_all:
|
||||
CUFREE(xdev); CUFREE(ydev);
|
||||
CUFREE(imdev); CUFREE(bdev);
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
13
src/README
Normal file
13
src/README
Normal file
@ -0,0 +1,13 @@
|
||||
1. Многопоточные функции поместить в обертку: если есть куда, пытаться сначала вызвать куду, если не сработало или куды нет --
|
||||
выполнять на CPU. Все #pragma omp заключить в "скобки": #ifdef OMP ... #endif
|
||||
|
||||
2. Флаг отладки - EBUG
|
||||
|
||||
3. Русифицировать gettext'ом
|
||||
|
||||
4. cmake -DLOCALEDIR=dir изменяет директорию с локалью (снаружи)
|
||||
|
||||
|
||||
|
||||
ВСЕ ПРОСТРАНСТВЕННЫЕ КООРДИНАТЫ ПРАВОВИНТОВЫЕ
|
||||
НА ИЗОБРАЖЕНИЯХ ОСЬ Y Н
|
||||
299
src/cmdlnopts.c
Normal file
299
src/cmdlnopts.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* cmdlnopts.c - the only function that parce cmdln args and returns glob parameters
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>*/
|
||||
#include "cmdlnopts.h"
|
||||
|
||||
|
||||
// global variables for parsing
|
||||
glob_pars G;
|
||||
mirPar M;
|
||||
int help;
|
||||
// don't rewrite existing files: for saveimg.c
|
||||
extern int rewrite_ifexists;
|
||||
/*
|
||||
* variables for mkHartmann.c
|
||||
*/
|
||||
extern char *outpfile; // output file name for saving matrixes
|
||||
extern int printDebug; // print tabulars with data on screen or to file
|
||||
extern int save_images;// save intermediate results to images
|
||||
|
||||
// suboptions structure for get_suboptions
|
||||
// in array last MUST BE {0,0,0}
|
||||
typedef struct{
|
||||
float *val; // pointer to result
|
||||
char *par; // parameter name (CASE-INSENSITIVE!)
|
||||
bool isdegr; // == TRUE if parameter is an angle in format "[+-][DDd][MMm][SS.S]"
|
||||
} suboptions;
|
||||
|
||||
// DEFAULTS
|
||||
// default global parameters
|
||||
glob_pars const Gdefault = {
|
||||
8, // size of initial array of surface deviations
|
||||
100, // size of interpolated S0
|
||||
1000, // resulting image size
|
||||
10000, // amount of photons falled to one pixel of S1 by one iteration
|
||||
0, // add to mask random numbers
|
||||
1e-8, // amplitude of added random noice
|
||||
IT_FITS,// output image type
|
||||
NULL, // input deviations file name
|
||||
NULL // mirror
|
||||
};
|
||||
//default mirror parameters
|
||||
mirPar const Mdefault = {
|
||||
6., // diameter
|
||||
24.024, // focus
|
||||
0., // inclination from Z axe (radians)
|
||||
0., // azimuth of inclination (radians)
|
||||
0., // azimuth of object (radians)
|
||||
0., // zenith of object (radians)
|
||||
23.9, // Z-coordinate of light receiver
|
||||
NULL // diaphragm
|
||||
};
|
||||
|
||||
bool get_mir_par(void *arg, int N);
|
||||
bool get_imtype(void *arg, int N);
|
||||
|
||||
char MirPar[] = N_("set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Ao=ang:Zo=ang:C=num]\n" \
|
||||
"\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like -10m13.4 !\n" \
|
||||
"\t\tdiam - diameter of mirror\n" \
|
||||
"\t\tfoc - mirror focus ratio\n" \
|
||||
"\t\tZincl - inclination from Z axe\n" \
|
||||
"\t\tAincl - azimuth of inclination\n" \
|
||||
"\t\tAobj - azimuth of object\n" \
|
||||
"\t\tZobj - zenith of object\n" \
|
||||
"\t\tccd - Z-coordinate of light receiver");
|
||||
|
||||
// name has_arg flag val type argptr help
|
||||
myoption cmdlnopts[] = {
|
||||
{"help", 0, NULL, 'h', arg_int, APTR(&help), N_("show this help")},
|
||||
{"dev-size",1, NULL, 'd', arg_int, APTR(&G.S_dev), N_("size of initial array of surface deviations")},
|
||||
{"int-size",1, NULL, 'i', arg_int, APTR(&G.S_interp), N_("size of interpolated array of surface deviations")},
|
||||
{"image-size",1,NULL, 'I', arg_int, APTR(&G.S_image), N_("resulting image size")},
|
||||
{"N-photons",1,NULL, 'N', arg_int, APTR(&G.N_phot), N_("amount of photons falled to one pixel of matrix by one iteration")},
|
||||
{"mir-parameters",1,NULL,'M', arg_function,APTR(&get_mir_par),MirPar},
|
||||
{"add-noice",0, &G.randMask,1, arg_none, NULL, N_("add random noice to mirror surface deviations")},
|
||||
{"noice-amp",1, NULL, 'a', arg_float, APTR(&G.randAmp), N_("amplitude of random noice (default: 1e-8)")},
|
||||
{"dev-file", 1, NULL, 'F', arg_string, APTR(&G.dev_filename),N_("filename for mirror surface deviations (in microns!)")},
|
||||
{"force", 0, &rewrite_ifexists,1,arg_none,NULL, N_("rewrite output file if exists")},
|
||||
{"log-file",1, NULL, 'l', arg_string, APTR(&outpfile), N_("save matrices to file arg")},
|
||||
{"print-matr",0,&printDebug,1, arg_none, NULL, N_("print matrices on screen")},
|
||||
{"save-images",0,&save_images,1,arg_none, NULL, N_("save intermediate results to images")},
|
||||
{"image-type",1,NULL, 'T', arg_function,APTR(&get_imtype), N_("image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)")},
|
||||
end_option
|
||||
};
|
||||
|
||||
/**
|
||||
* Safely convert data from string to float
|
||||
*
|
||||
* @param num (o) - float number read from string
|
||||
* @param str (i) - input string
|
||||
* @return TRUE if success
|
||||
*/
|
||||
bool myatof(float *num, const char *str){
|
||||
float res;
|
||||
char *endptr;
|
||||
assert(str);
|
||||
res = strtof(str, &endptr);
|
||||
if(endptr == str || *str == '\0' || *endptr != '\0'){
|
||||
WARNX(_("Wrong float number format!"));
|
||||
return FALSE;
|
||||
}
|
||||
*num = res;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string "[+-][DDd][MMm][SS.S]" into radians
|
||||
*
|
||||
* @param ang (o) - angle in radians or exit with help message
|
||||
* @param str (i) - string with angle
|
||||
* @return TRUE if OK
|
||||
*/
|
||||
bool get_radians(float *ret, char *str){
|
||||
float val = 0., ftmp, sign = 1.;
|
||||
char *ptr;
|
||||
assert(str);
|
||||
switch(*str){ // check sign
|
||||
case '-':
|
||||
sign = -1.;
|
||||
case '+':
|
||||
str++;
|
||||
}
|
||||
if((ptr = strchr(str, 'd'))){ // found DDD.DDd
|
||||
*ptr = 0; if(!myatof(&ftmp, str)) return FALSE;
|
||||
ftmp = fabs(ftmp);
|
||||
if(ftmp > 360.){
|
||||
WARNX(_("Degrees should be less than 360"));
|
||||
return FALSE;
|
||||
}
|
||||
val += ftmp;
|
||||
str = ptr + 1;
|
||||
}
|
||||
if((ptr = strchr(str, 'm'))){ // found DDD.DDm
|
||||
*ptr = 0; if(!myatof(&ftmp, str)) return FALSE;
|
||||
ftmp = fabs(ftmp);
|
||||
/*if(ftmp >= 60.){
|
||||
WARNX(_("Minutes should be less than 60"));
|
||||
return FALSE;
|
||||
}*/
|
||||
val += ftmp / 60.;
|
||||
str = ptr + 1;
|
||||
}
|
||||
if(strlen(str)){ // there is something more
|
||||
if(!myatof(&ftmp, str)) return FALSE;
|
||||
ftmp = fabs(ftmp);
|
||||
/*if(ftmp >= 60.){
|
||||
WARNX(_("Seconds should be less than 60"));
|
||||
return FALSE;
|
||||
}*/
|
||||
val += ftmp / 3600.;
|
||||
}
|
||||
DBG("Angle: %g degr", val*sign);
|
||||
*ret = D2R(val * sign); // convert degrees to radians
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse string of suboptions (--option=name1=var1:name2=var2... or -O name1=var1,name2=var2...)
|
||||
* Suboptions could be divided by colon or comma
|
||||
*
|
||||
* !!NAMES OF SUBOPTIONS ARE CASE-UNSENSITIVE!!!
|
||||
*
|
||||
* @param arg (i) - string with description
|
||||
* @param V (io) - pointer to suboptions array (result will be stored in sopts->val)
|
||||
* @return TRUE if success
|
||||
*/
|
||||
bool get_suboptions(void *arg, suboptions *V){
|
||||
char *tok, *val, *par;
|
||||
int i;
|
||||
tok = strtok(arg, ":,");
|
||||
do{
|
||||
if((val = strchr(tok, '=')) == NULL){ // wrong format
|
||||
WARNX(_("Wrong format: no value for keyword"));
|
||||
return FALSE;
|
||||
}
|
||||
*val++ = '\0';
|
||||
par = tok;
|
||||
for(i = 0; V[i].val; i++){
|
||||
if(strcasecmp(par, V[i].par) == 0){ // found parameter
|
||||
if(V[i].isdegr){ // DMS
|
||||
if(!get_radians(V[i].val, val)) // wrong angle
|
||||
return FALSE;
|
||||
DBG("Angle: %g rad\n", *(V[i].val));
|
||||
}else{ // simple float
|
||||
if(!myatof(V[i].val, val)) // wrong number
|
||||
return FALSE;
|
||||
DBG("Float val: %g\n", *(V[i].val));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!V[i].val){ // nothing found - wrong format
|
||||
WARNX(_("Bad keyword!"));
|
||||
return FALSE;
|
||||
}
|
||||
}while((tok = strtok(NULL, ":,")));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse string of mirror parameters (--mir-diam=...)
|
||||
*
|
||||
* @param arg (i) - string with description
|
||||
* @param N (i) - number of selected option (unused)
|
||||
* @return TRUE if success
|
||||
*/
|
||||
bool get_mir_par(void *arg, int N _U_){
|
||||
suboptions V[] = { // array of mirror parameters and string keys for cmdln pars
|
||||
{&M.D, "diam", FALSE},
|
||||
{&M.F, "foc", FALSE},
|
||||
{&M.Zincl, "zincl", TRUE},
|
||||
{&M.Aincl, "aincl", TRUE},
|
||||
{&M.objA, "aobj", TRUE},
|
||||
{&M.objZ, "zobj", TRUE},
|
||||
{&M.foc, "ccd", FALSE},
|
||||
{0,0,0}
|
||||
};
|
||||
return get_suboptions(arg, V);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parce command line options and return dynamically allocated structure
|
||||
* to global parameters
|
||||
* @param argc - copy of argc from main
|
||||
* @param argv - copy of argv from main
|
||||
* @return allocated structure with global parameters
|
||||
*/
|
||||
glob_pars *parce_args(int argc, char **argv){
|
||||
int i;
|
||||
void *ptr;
|
||||
ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr);
|
||||
ptr = memcpy(&M, &Mdefault, sizeof(M)); assert(ptr);
|
||||
G.Mirror = &M;
|
||||
// format of help: "Usage: progname [args]\n"
|
||||
change_helpstring("Usage: %s [args]\n\n\tWhere args are:\n");
|
||||
// parse arguments
|
||||
parceargs(&argc, &argv, cmdlnopts);
|
||||
if(help) showhelp(-1, cmdlnopts);
|
||||
if(argc > 0){
|
||||
printf("\nIgnore argument[s]:\n");
|
||||
for (i = 0; i < argc; i++)
|
||||
printf("\t%s\n", argv[i]);
|
||||
}
|
||||
return &G;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image type from command line parameter:
|
||||
* F/f for FITS
|
||||
* P/p for PNG
|
||||
* J/j for JPEG
|
||||
* T/t for TIFF
|
||||
* @param arg (i) - string with parameters
|
||||
* @return FALSE if fail
|
||||
*/
|
||||
bool get_imtype(void *arg, int N _U_){
|
||||
assert(arg);
|
||||
G.it = 0;
|
||||
do{
|
||||
switch(*((char*)arg)){
|
||||
case 'F': case 'f':
|
||||
G.it |= IT_FITS;
|
||||
break;
|
||||
case 'P': case 'p':
|
||||
G.it |= IT_PNG;
|
||||
break;
|
||||
case 'J': case 'j':
|
||||
G.it |= IT_JPEG;
|
||||
break;
|
||||
case 'T' : case 't':
|
||||
G.it |= IT_TIFF;
|
||||
break;
|
||||
default:
|
||||
WARNX(_("Wrong format of image type: %c"), *((char*)arg));
|
||||
return FALSE;
|
||||
}
|
||||
}while(*((char*)++arg));
|
||||
return TRUE;
|
||||
}
|
||||
298
src/diaphragm.c
Normal file
298
src/diaphragm.c
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* diaphragm.c - read diaphragm parameters from file
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "mkHartmann.h"
|
||||
#include "wrapper.h"
|
||||
#include "diaphragm.h"
|
||||
#include <sys/mman.h>
|
||||
#include <json/json.h>
|
||||
|
||||
/**
|
||||
* Get double value from object
|
||||
* @param jobj (i) - object
|
||||
* @return double value
|
||||
*/
|
||||
double get_jdouble(json_object *jobj){
|
||||
enum json_type type = json_object_get_type(jobj);
|
||||
double val;
|
||||
switch(type){
|
||||
case json_type_double:
|
||||
val = json_object_get_double(jobj);
|
||||
break;
|
||||
case json_type_int:
|
||||
val = json_object_get_int(jobj);
|
||||
break;
|
||||
default:
|
||||
ERRX(_("Wrong value! Get non-number!\n"));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill double array from json array object
|
||||
*
|
||||
* @param jobj (i) - JSON array
|
||||
* @param getLen (o) - array length or NULL
|
||||
* @return filled array
|
||||
*/
|
||||
double *json_get_array(json_object *jobj, int *getLen){
|
||||
enum json_type type;
|
||||
json_object *jarray = jobj;
|
||||
int arraylen = json_object_array_length(jarray);
|
||||
double *arr = calloc(arraylen, sizeof(double));
|
||||
int L = 0;
|
||||
int i;
|
||||
json_object *jvalue;
|
||||
for (i=0; i< arraylen; i++){
|
||||
jvalue = json_object_array_get_idx(jarray, i);
|
||||
type = json_object_get_type(jvalue);
|
||||
if(type == json_type_array){ // nested arrays is error
|
||||
ERRX(_("Invalid file format! Found nested arrays!\n"));
|
||||
}
|
||||
else if (type != json_type_object){
|
||||
arr[L++] = get_jdouble(jvalue);
|
||||
}
|
||||
else{ // non-numerical data?
|
||||
ERRX(_("Invalid file format! Non-numerical data in array!\n"));
|
||||
}
|
||||
}
|
||||
if(L == 0) FREE(arr);
|
||||
if(getLen) *getLen = L;
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read bounding box from JSON object
|
||||
*
|
||||
* @param B (o) - output BBox (allocated outside)
|
||||
* @param jobj (i) - JSON object (array with BBox params)
|
||||
*/
|
||||
void json_get_bbox(BBox *B, json_object *jobj){
|
||||
double *arr = NULL;
|
||||
int Len;
|
||||
assert(B); assert(jobj);
|
||||
json_object *o = json_object_object_get(jobj, "bbox");
|
||||
if(!o) return;
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 4){
|
||||
ERRX(_("\"bbox\" must contain an array of four doubles!\n"));
|
||||
}
|
||||
B->x0 = arr[0]; B->y0 = arr[1]; B->w = arr[2]; B->h = arr[3];
|
||||
FREE(arr);
|
||||
}
|
||||
|
||||
aHole globHole; // global parameters for all holes (in beginning of diafragm JSON)
|
||||
/**
|
||||
* Fills aHole object by data in JSON
|
||||
* @param jobj (i) - JSON data for hole
|
||||
* @param H (o) - output hole object
|
||||
*/
|
||||
void get_obj_params(json_object *jobj, aHole *H){
|
||||
double *arr = NULL;
|
||||
int Len;
|
||||
enum json_type type;
|
||||
if(!H){
|
||||
ERRX( _("Error: NULL instead of aHole structure!\n"));
|
||||
}
|
||||
memcpy(H, &globHole, sizeof(aHole)); // initialize hole by global values
|
||||
json_object *o = json_object_object_get(jobj, "shape");
|
||||
if(o){
|
||||
const char *ptr = json_object_get_string(o);
|
||||
if(strcmp(ptr, "square") == 0) H->type = H_SQUARE;
|
||||
else if(strcmp(ptr, "round") == 0 || strcmp(ptr, "ellipse") == 0 ) H->type = H_ELLIPSE;
|
||||
else H->type = H_UNDEF;
|
||||
}
|
||||
o = json_object_object_get(jobj, "radius");
|
||||
if(o){
|
||||
type = json_object_get_type(o);
|
||||
if(type == json_type_int || type == json_type_double){ // circle / square
|
||||
double R = json_object_get_double(o);
|
||||
H->box.w = H->box.h = R * 2.;
|
||||
}else if(type == json_type_array){ // ellipse / rectangle
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 2){
|
||||
ERRX(_("\"radius\" array must consist of two doubles!\n"));
|
||||
}
|
||||
H->box.w = arr[0] * 2.; H->box.h = arr[1] * 2.;
|
||||
FREE(arr);
|
||||
}else{
|
||||
ERRX(_("\"radius\" must be a number or an array of two doubles!\n"));
|
||||
}
|
||||
}
|
||||
o = json_object_object_get(jobj, "center");
|
||||
if(o){
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 2){
|
||||
ERRX(_("\"center\" must contain an array of two doubles!\n"));
|
||||
}
|
||||
H->box.x0 = arr[0] - H->box.w/2.;
|
||||
H->box.y0 = arr[1] - H->box.h/2.;
|
||||
FREE(arr);
|
||||
}else{
|
||||
json_get_bbox(&H->box, jobj);
|
||||
/* o = json_object_object_get(jobj, "bbox");
|
||||
if(o){
|
||||
if(!(arr = json_get_array(o, &Len)) || Len != 4){
|
||||
ERRX(_("\"bbox\" must contain an array of four doubles!\n"));
|
||||
}
|
||||
H->box.x0 = arr[0]; H->box.y0 = arr[1]; H->box.w = arr[2]; H->box.h = arr[3];
|
||||
FREE(arr);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill array of holes from JSON data
|
||||
*
|
||||
* @param jobj (i) - JSON array with holes data
|
||||
* @param getLen (o) - length of array or NULL
|
||||
* @return holes array
|
||||
*/
|
||||
aHole *json_parse_holesarray(json_object *jobj, int *getLen){
|
||||
enum json_type type;
|
||||
json_object *jarray = jobj;
|
||||
int arraylen = json_object_array_length(jarray), i;
|
||||
aHole *H = calloc(arraylen, sizeof(aHole));
|
||||
json_object *jvalue;
|
||||
for (i=0; i < arraylen; i++){
|
||||
jvalue = json_object_array_get_idx(jarray, i);
|
||||
type = json_object_get_type(jvalue);
|
||||
if(type == json_type_object){
|
||||
get_obj_params(jvalue, &H[i]);
|
||||
}else{
|
||||
ERRX(_("Invalid holes array format!\n"));
|
||||
}
|
||||
}
|
||||
if(getLen) *getLen = arraylen;
|
||||
return H;
|
||||
}
|
||||
|
||||
#ifdef EBUG
|
||||
char *gettype(aHole *H){
|
||||
char *ret;
|
||||
switch(H->type){
|
||||
case H_SQUARE:
|
||||
ret = "square";
|
||||
break;
|
||||
case H_ELLIPSE:
|
||||
ret = "ellipse";
|
||||
break;
|
||||
default:
|
||||
ret = "undefined";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Try to mmap a file
|
||||
*
|
||||
* @param filename (i) - name of file to mmap
|
||||
* @return pointer with mmap'ed file or die
|
||||
*/
|
||||
char *My_mmap(char *filename, size_t *Mlen){
|
||||
int fd;
|
||||
char *ptr;
|
||||
struct stat statbuf;
|
||||
if(!filename) ERRX(_("No filename given!"));
|
||||
if((fd = open(filename, O_RDONLY)) < 0)
|
||||
ERR(_("Can't open %s for reading"), filename);
|
||||
if(fstat (fd, &statbuf) < 0)
|
||||
ERR(_("Can't stat %s"), filename);
|
||||
*Mlen = statbuf.st_size;
|
||||
if((ptr = mmap (0, *Mlen, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
|
||||
ERR(_("Mmap error for input"));
|
||||
if(close(fd)) ERR(_("Can't close mmap'ed file"));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read holes array for diaphragm structure from file
|
||||
*
|
||||
* file should
|
||||
*
|
||||
* @param filename - name of file
|
||||
* @return readed structure or NULL if failed
|
||||
*/
|
||||
aHole *readHoles(char *filename, Diaphragm *dia){
|
||||
char *ptr;
|
||||
enum json_type type;
|
||||
json_object *o, *jobj;
|
||||
int i, HolesNum;
|
||||
aHole *HolesArray;
|
||||
BBox Dbox = {100.,100.,-200.,-200.}; // bounding box of diaphragm
|
||||
size_t Mlen;
|
||||
if(dia) memset(dia, 0, sizeof(Diaphragm));
|
||||
ptr = My_mmap(filename, &Mlen);
|
||||
jobj = json_tokener_parse(ptr);
|
||||
get_obj_params(jobj, &globHole); // read global parameters
|
||||
// now try to find diaphragm bounding box & Z-coordinate
|
||||
json_get_bbox(&Dbox, jobj);
|
||||
// check for Z-coordinate
|
||||
if(dia){
|
||||
o = json_object_object_get(jobj, "Z");
|
||||
if(!o) o = json_object_object_get(jobj, "maskz");
|
||||
if(!o)
|
||||
ERRX(_("JSON file MUST contain floating point field \"Z\" or \"maskz\" with mask's coordinate"));
|
||||
dia->Z = get_jdouble(o); // read mask Z
|
||||
}
|
||||
o = json_object_object_get(jobj, "holes");
|
||||
if(!o)
|
||||
ERRX(_("Corrupted file: no holes found!"));
|
||||
type = json_object_get_type(o);
|
||||
if(type == json_type_object){ // single hole
|
||||
HolesArray = calloc(1, sizeof(aHole));
|
||||
assert(HolesArray);
|
||||
HolesNum = 1;
|
||||
get_obj_params(o, HolesArray);
|
||||
}else{ // array of holes
|
||||
HolesArray = json_parse_holesarray(o, &HolesNum);
|
||||
}
|
||||
if(!HolesArray || HolesNum < 1)
|
||||
ERRX(_("Didn't find any holes in json file!"));
|
||||
DBG("Readed %d holes", HolesNum);
|
||||
// check bbox of diafragm (or make it if none)
|
||||
float minx=100., miny=100., maxx=-100., maxy=-100.;
|
||||
for(i = 0; i < HolesNum; i++){
|
||||
BBox *B = &HolesArray[i].box;
|
||||
float L=B->x0, R=L+B->w, D=B->y0, U=D+B->h;
|
||||
if(minx > L) minx = L;
|
||||
if(maxx < R) maxx = R;
|
||||
if(miny > D) miny = D;
|
||||
if(maxy < U) maxy = U;
|
||||
#ifdef EBUG
|
||||
green("Hole %4d:", i);
|
||||
printf(" type =%9s, bbox = {%7.4f, %7.4f, %7.4f, %7.4f }\n", gettype(&HolesArray[i]),
|
||||
B->x0, B->y0, B->w, B->h);
|
||||
#endif
|
||||
}
|
||||
float wdth = maxx - minx + 0.1, hght = maxy - miny + 0.1; // width & height of bbox
|
||||
// now correct bbox (or fill it if it wasn't in JSON)
|
||||
if(Dbox.x0 > minx) Dbox.x0 = minx;
|
||||
if(Dbox.y0 > miny) Dbox.y0 = miny;
|
||||
if(Dbox.w < wdth) Dbox.w = wdth;
|
||||
if(Dbox.h < hght) Dbox.h = hght;
|
||||
munmap(ptr, Mlen);
|
||||
if(dia){
|
||||
dia->holes = HolesArray;
|
||||
dia->Nholes = HolesNum;
|
||||
memcpy(&dia->box, &Dbox, sizeof(BBox));
|
||||
}
|
||||
return HolesArray;
|
||||
}
|
||||
|
||||
48
src/include/cmdlnopts.h
Normal file
48
src/include/cmdlnopts.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* cmdlnopts.h - comand line options for parceargs
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __CMDLNOPTS_H__
|
||||
#define __CMDLNOPTS_H__
|
||||
|
||||
#include "parceargs.h"
|
||||
#include "mkHartmann.h"
|
||||
#include "saveimg.h"
|
||||
|
||||
typedef struct{
|
||||
int S_dev; // size of initial array of surface deviations
|
||||
int S_interp; // size of interpolated S0
|
||||
int S_image; // resulting image size
|
||||
int N_phot; // amount of photons falled to one pixel of S1 by one iteration
|
||||
int randMask; // add to mask random numbers
|
||||
float randAmp; // amplitude of added random noice
|
||||
imtype it; // output image type
|
||||
char *dev_filename;// input deviations file name
|
||||
mirPar *Mirror; // mirror parameters
|
||||
} glob_pars;
|
||||
|
||||
// default parameters
|
||||
extern glob_pars const Gdefault;
|
||||
extern mirPar const Mdefault;
|
||||
|
||||
glob_pars *parce_args(int argc, char **argv);
|
||||
|
||||
#endif // __CMDLNOPTS_H__
|
||||
772
src/include/cutil_math.h
Normal file
772
src/include/cutil_math.h
Normal file
@ -0,0 +1,772 @@
|
||||
/*
|
||||
* Copyright 1993-2007 NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* NOTICE TO USER:
|
||||
*
|
||||
* This source code is subject to NVIDIA ownership rights under U.S. and
|
||||
* international Copyright laws. Users and possessors of this source code
|
||||
* are hereby granted a nonexclusive, royalty-free license to use this code
|
||||
* in individual and commercial software.
|
||||
*
|
||||
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
|
||||
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
|
||||
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
|
||||
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||
* OR PERFORMANCE OF THIS SOURCE CODE.
|
||||
*
|
||||
* U.S. Government End Users. This source code is a "commercial item" as
|
||||
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
|
||||
* "commercial computer software" and "commercial computer software
|
||||
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
|
||||
* and is provided to the U.S. Government only as a commercial end item.
|
||||
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
|
||||
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
|
||||
* source code with only those rights set forth herein.
|
||||
*
|
||||
* Any use of this source code in individual and commercial software must
|
||||
* include, in the user documentation and internal comments to the code,
|
||||
* the above Disclaimer and U.S. Government End Users Notice.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file implements common mathematical operations on vector types
|
||||
(float3, float4 etc.) since these are not provided as standard by CUDA.
|
||||
|
||||
The syntax is modelled on the Cg standard library.
|
||||
*/
|
||||
|
||||
// This software contains source code provided by NVIDIA Corporation.
|
||||
// This header contains some bug fixes by Danny Ruijters, changed locations
|
||||
// are marked with "Danny".
|
||||
#ifndef CUTIL_MATH_BUGFIXES_H
|
||||
#define CUTIL_MATH_BUGFIXES_H
|
||||
|
||||
#ifdef CUTIL_MATH_H //Danny
|
||||
// Houston, we have a problem!!!
|
||||
// It seems that the buggy cutil_math.h has already been included, and this
|
||||
// clashes with this header file.
|
||||
#error cutil_math_bugfixes.h has to be included before cutil_math.h!!!
|
||||
#endif
|
||||
#define CUTIL_MATH_H //make sure that the buggy cutil_math.h will not be included
|
||||
|
||||
#include "cuda_runtime.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned short ushort;
|
||||
|
||||
#ifndef __CUDACC__
|
||||
#include <math.h>
|
||||
|
||||
inline float fminf(float a, float b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline float fmaxf(float a, float b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline int max(int a, int b)
|
||||
{
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
inline int min(int a, int b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
#endif
|
||||
|
||||
// float functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// lerp
|
||||
inline __device__ __host__ float lerp(float a, float b, float t)
|
||||
{
|
||||
return a + t*(b-a);
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ float clamp(float f, float a, float b)
|
||||
{
|
||||
return fmaxf(a, fminf(f, b));
|
||||
}
|
||||
|
||||
// int2 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ int2 operator+(int2 a, int2 b)
|
||||
{
|
||||
return make_int2(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(int2 &a, int2 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ int2 operator-(int2 a, int2 b)
|
||||
{
|
||||
return make_int2(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
inline __host__ __device__ void operator-=(int2 &a, int2 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ int2 operator*(int2 a, int2 b)
|
||||
{
|
||||
return make_int2(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
inline __host__ __device__ int2 operator*(int2 a, int s)
|
||||
{
|
||||
return make_int2(a.x * s, a.y * s);
|
||||
}
|
||||
inline __host__ __device__ int2 operator*(int s, int2 a)
|
||||
{
|
||||
return make_int2(a.x * s, a.y * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(int2 &a, int s)
|
||||
{
|
||||
a.x *= s; a.y *= s;
|
||||
}
|
||||
|
||||
// float2 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// additional constructors
|
||||
inline __host__ __device__ float2 make_float2(float s)
|
||||
{
|
||||
return make_float2(s, s);
|
||||
}
|
||||
inline __host__ __device__ float2 make_float2(int2 a)
|
||||
{
|
||||
return make_float2(float(a.x), float(a.y));
|
||||
}
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ float2 operator+(float2 a, float2 b)
|
||||
{
|
||||
return make_float2(a.x + b.x, a.y + b.y);
|
||||
}
|
||||
inline __host__ __device__ float2 operator+(float2 a, float b)
|
||||
{
|
||||
return make_float2(a.x + b, a.y + b);
|
||||
}
|
||||
inline __host__ __device__ float2 operator+(float a, float2 b)
|
||||
{
|
||||
return make_float2(a + b.x, a + b.y);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(float2 &a, float2 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y;
|
||||
}
|
||||
inline __host__ __device__ void operator+=(float2 &a, float b)
|
||||
{
|
||||
a.x += b; a.y += b;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ float2 operator-(float2 a, float2 b)
|
||||
{
|
||||
return make_float2(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
inline __host__ __device__ float2 operator-(float a, float2 b)
|
||||
{
|
||||
return make_float2(a - b.x, a - b.y);
|
||||
}
|
||||
inline __host__ __device__ float2 operator-(float2 a, float b)
|
||||
{
|
||||
return make_float2(a.x - b, a.y - b);
|
||||
}
|
||||
inline __host__ __device__ void operator-=(float2 &a, float2 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y;
|
||||
}
|
||||
inline __host__ __device__ void operator-=(float2 &a, float b)
|
||||
{
|
||||
a.x -= b; a.y -= b;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ float2 operator*(float2 a, float2 b)
|
||||
{
|
||||
return make_float2(a.x * b.x, a.y * b.y);
|
||||
}
|
||||
inline __host__ __device__ float2 operator*(float2 a, float s)
|
||||
{
|
||||
return make_float2(a.x * s, a.y * s);
|
||||
}
|
||||
inline __host__ __device__ float2 operator*(float s, float2 a)
|
||||
{
|
||||
return make_float2(a.x * s, a.y * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(float2 &a, float s)
|
||||
{
|
||||
a.x *= s; a.y *= s;
|
||||
}
|
||||
|
||||
// divide
|
||||
inline __host__ __device__ float2 operator/(float2 a, float2 b)
|
||||
{
|
||||
return make_float2(a.x / b.x, a.y / b.y);
|
||||
}
|
||||
inline __host__ __device__ float2 operator/(float2 a, float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
return a * inv;
|
||||
}
|
||||
inline __host__ __device__ float2 operator/(float s, float2 a)
|
||||
{
|
||||
return make_float2(s / a.x, s / a.y);
|
||||
}
|
||||
inline __host__ __device__ void operator/=(float2 &a, float s)
|
||||
{
|
||||
a.x /= s; a.y /= s;
|
||||
}
|
||||
|
||||
// lerp
|
||||
inline __device__ __host__ float2 lerp(float2 a, float2 b, float t)
|
||||
{
|
||||
return a + t*(b-a);
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ float2 clamp(float2 v, float a, float b)
|
||||
{
|
||||
return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b)
|
||||
{
|
||||
return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
|
||||
}
|
||||
|
||||
// dot product
|
||||
inline __host__ __device__ float dot(float2 a, float2 b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y;
|
||||
}
|
||||
|
||||
// length
|
||||
inline __host__ __device__ float length(float2 v)
|
||||
{
|
||||
return sqrtf(dot(v, v));
|
||||
}
|
||||
|
||||
// normalize
|
||||
inline __host__ __device__ float2 normalize(float2 v)
|
||||
{
|
||||
float invLen = 1.0f / sqrtf(dot(v, v));
|
||||
return v * invLen;
|
||||
}
|
||||
|
||||
// floor
|
||||
inline __host__ __device__ float2 floor(const float2 v)
|
||||
{
|
||||
return make_float2(floor(v.x), floor(v.y));
|
||||
}
|
||||
|
||||
// reflect
|
||||
inline __host__ __device__ float2 reflect(float2 i, float2 n)
|
||||
{
|
||||
return i - 2.0f * n * dot(n,i);
|
||||
}
|
||||
|
||||
// float3 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// additional constructors
|
||||
inline __host__ __device__ float3 make_float3(float s)
|
||||
{
|
||||
return make_float3(s, s, s);
|
||||
}
|
||||
inline __host__ __device__ float3 make_float3(float2 a)
|
||||
{
|
||||
return make_float3(a.x, a.y, 0.0f);
|
||||
}
|
||||
inline __host__ __device__ float3 make_float3(float2 a, float s)
|
||||
{
|
||||
return make_float3(a.x, a.y, s);
|
||||
}
|
||||
inline __host__ __device__ float3 make_float3(float4 a)
|
||||
{
|
||||
return make_float3(a.x, a.y, a.z); // discards w
|
||||
}
|
||||
inline __host__ __device__ float3 make_float3(int3 a)
|
||||
{
|
||||
return make_float3(float(a.x), float(a.y), float(a.z));
|
||||
}
|
||||
|
||||
// min
|
||||
static __inline__ __host__ __device__ float3 fminf(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
|
||||
}
|
||||
|
||||
// max
|
||||
static __inline__ __host__ __device__ float3 fmaxf(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
|
||||
}
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ float3 operator+(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
inline __host__ __device__ float3 operator+(float3 a, float b)
|
||||
{
|
||||
return make_float3(a.x + b, a.y + b, a.z + b);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(float3 &a, float3 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y; a.z += b.z;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ float3 operator-(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
inline __host__ __device__ float3 operator-(float3 a, float b)
|
||||
{
|
||||
return make_float3(a.x - b, a.y - b, a.z - b);
|
||||
}
|
||||
inline __host__ __device__ void operator-=(float3 &a, float3 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y; a.z -= b.z;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ float3 operator*(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
}
|
||||
inline __host__ __device__ float3 operator*(float3 a, float s)
|
||||
{
|
||||
return make_float3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ float3 operator*(float s, float3 a)
|
||||
{
|
||||
return make_float3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(float3 &a, float s)
|
||||
{
|
||||
a.x *= s; a.y *= s; a.z *= s;
|
||||
}
|
||||
|
||||
// divide
|
||||
inline __host__ __device__ float3 operator/(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||
}
|
||||
inline __host__ __device__ float3 operator/(float3 a, float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
return a * inv;
|
||||
}
|
||||
inline __host__ __device__ float3 operator/(float s, float3 a) //Danny
|
||||
{
|
||||
// float inv = 1.0f / s;
|
||||
// return a * inv;
|
||||
return make_float3(s / a.x, s / a.y, s / a.z);
|
||||
}
|
||||
inline __host__ __device__ void operator/=(float3 &a, float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
a *= inv;
|
||||
}
|
||||
|
||||
// lerp
|
||||
inline __device__ __host__ float3 lerp(float3 a, float3 b, float t)
|
||||
{
|
||||
return a + t*(b-a);
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ float3 clamp(float3 v, float a, float b)
|
||||
{
|
||||
return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b)
|
||||
{
|
||||
return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
|
||||
}
|
||||
|
||||
// dot product
|
||||
inline __host__ __device__ float dot(float3 a, float3 b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
// cross product
|
||||
inline __host__ __device__ float3 cross(float3 a, float3 b)
|
||||
{
|
||||
return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
|
||||
}
|
||||
|
||||
// length
|
||||
inline __host__ __device__ float length(float3 v)
|
||||
{
|
||||
return sqrtf(dot(v, v));
|
||||
}
|
||||
|
||||
// normalize
|
||||
inline __host__ __device__ float3 normalize(float3 v)
|
||||
{
|
||||
float invLen = 1.0f / sqrtf(dot(v, v));
|
||||
return v * invLen;
|
||||
}
|
||||
|
||||
// floor
|
||||
inline __host__ __device__ float3 floor(const float3 v)
|
||||
{
|
||||
return make_float3(floor(v.x), floor(v.y), floor(v.z));
|
||||
}
|
||||
|
||||
// reflect
|
||||
inline __host__ __device__ float3 reflect(float3 i, float3 n)
|
||||
{
|
||||
return i - 2.0f * n * dot(n,i);
|
||||
}
|
||||
|
||||
// float4 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// additional constructors
|
||||
inline __host__ __device__ float4 make_float4(float s)
|
||||
{
|
||||
return make_float4(s, s, s, s);
|
||||
}
|
||||
inline __host__ __device__ float4 make_float4(float3 a)
|
||||
{
|
||||
return make_float4(a.x, a.y, a.z, 0.0f);
|
||||
}
|
||||
inline __host__ __device__ float4 make_float4(float3 a, float w)
|
||||
{
|
||||
return make_float4(a.x, a.y, a.z, w);
|
||||
}
|
||||
inline __host__ __device__ float4 make_float4(int4 a)
|
||||
{
|
||||
return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
|
||||
}
|
||||
|
||||
// min
|
||||
static __inline__ __host__ __device__ float4 fminf(float4 a, float4 b)
|
||||
{
|
||||
return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w));
|
||||
}
|
||||
|
||||
// max
|
||||
static __inline__ __host__ __device__ float4 fmaxf(float4 a, float4 b)
|
||||
{
|
||||
return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w));
|
||||
}
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ float4 operator+(float4 a, float4 b)
|
||||
{
|
||||
return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(float4 &a, float4 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ float4 operator-(float4 a, float4 b)
|
||||
{
|
||||
return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
|
||||
}
|
||||
inline __host__ __device__ void operator-=(float4 &a, float4 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ float4 operator*(float4 a, float s)
|
||||
{
|
||||
return make_float4(a.x * s, a.y * s, a.z * s, a.w * s);
|
||||
}
|
||||
inline __host__ __device__ float4 operator*(float s, float4 a)
|
||||
{
|
||||
return make_float4(a.x * s, a.y * s, a.z * s, a.w * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(float4 &a, float s)
|
||||
{
|
||||
a.x *= s; a.y *= s; a.z *= s; a.w *= s;
|
||||
}
|
||||
|
||||
// divide
|
||||
inline __host__ __device__ float4 operator/(float4 a, float4 b)
|
||||
{
|
||||
return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
|
||||
}
|
||||
inline __host__ __device__ float4 operator/(float4 a, float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
return a * inv;
|
||||
}
|
||||
inline __host__ __device__ float4 operator/(float s, float4 a) //Danny
|
||||
{
|
||||
// float inv = 1.0f / s;
|
||||
// return a * inv;
|
||||
return make_float4(s / a.x, s / a.y, s / a.z, s / a.w);
|
||||
}
|
||||
inline __host__ __device__ void operator/=(float4 &a, float s)
|
||||
{
|
||||
float inv = 1.0f / s;
|
||||
a *= inv;
|
||||
}
|
||||
|
||||
// lerp
|
||||
inline __device__ __host__ float4 lerp(float4 a, float4 b, float t)
|
||||
{
|
||||
return a + t*(b-a);
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ float4 clamp(float4 v, float a, float b)
|
||||
{
|
||||
return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b)
|
||||
{
|
||||
return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
|
||||
}
|
||||
|
||||
// dot product
|
||||
inline __host__ __device__ float dot(float4 a, float4 b)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
}
|
||||
|
||||
// length
|
||||
inline __host__ __device__ float length(float4 r)
|
||||
{
|
||||
return sqrtf(dot(r, r));
|
||||
}
|
||||
|
||||
// normalize
|
||||
inline __host__ __device__ float4 normalize(float4 v)
|
||||
{
|
||||
float invLen = 1.0f / sqrtf(dot(v, v));
|
||||
return v * invLen;
|
||||
}
|
||||
|
||||
// floor
|
||||
inline __host__ __device__ float4 floor(const float4 v)
|
||||
{
|
||||
return make_float4(floor(v.x), floor(v.y), floor(v.z), floor(v.w));
|
||||
}
|
||||
|
||||
// int3 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// additional constructors
|
||||
inline __host__ __device__ int3 make_int3(int s)
|
||||
{
|
||||
return make_int3(s, s, s);
|
||||
}
|
||||
inline __host__ __device__ int3 make_int3(float3 a)
|
||||
{
|
||||
return make_int3(int(a.x), int(a.y), int(a.z));
|
||||
}
|
||||
|
||||
// min
|
||||
inline __host__ __device__ int3 min(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
|
||||
}
|
||||
|
||||
// max
|
||||
inline __host__ __device__ int3 max(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
|
||||
}
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ int3 operator+(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(int3 &a, int3 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y; a.z += b.z;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ int3 operator-(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
inline __host__ __device__ void operator-=(int3 &a, int3 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y; a.z -= b.z;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ int3 operator*(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
}
|
||||
inline __host__ __device__ int3 operator*(int3 a, int s)
|
||||
{
|
||||
return make_int3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ int3 operator*(int s, int3 a)
|
||||
{
|
||||
return make_int3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(int3 &a, int s)
|
||||
{
|
||||
a.x *= s; a.y *= s; a.z *= s;
|
||||
}
|
||||
|
||||
// divide
|
||||
inline __host__ __device__ int3 operator/(int3 a, int3 b)
|
||||
{
|
||||
return make_int3(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||
}
|
||||
inline __host__ __device__ int3 operator/(int3 a, int s)
|
||||
{
|
||||
return make_int3(a.x / s, a.y / s, a.z / s);
|
||||
}
|
||||
inline __host__ __device__ int3 operator/(int s, int3 a)
|
||||
{
|
||||
return make_int3(a.x / s, a.y / s, a.z / s);
|
||||
}
|
||||
inline __host__ __device__ void operator/=(int3 &a, int s)
|
||||
{
|
||||
a.x /= s; a.y /= s; a.z /= s;
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ int clamp(int f, int a, int b)
|
||||
{
|
||||
return max(a, min(f, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ int3 clamp(int3 v, int a, int b)
|
||||
{
|
||||
return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b)
|
||||
{
|
||||
return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
|
||||
}
|
||||
|
||||
|
||||
// uint3 functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// additional constructors
|
||||
inline __host__ __device__ uint3 make_uint3(uint s)
|
||||
{
|
||||
return make_uint3(s, s, s);
|
||||
}
|
||||
inline __host__ __device__ uint3 make_uint3(float3 a)
|
||||
{
|
||||
return make_uint3(uint(a.x), uint(a.y), uint(a.z));
|
||||
}
|
||||
|
||||
// min
|
||||
inline __host__ __device__ uint3 min(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
|
||||
}
|
||||
|
||||
// max
|
||||
inline __host__ __device__ uint3 max(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
|
||||
}
|
||||
|
||||
// addition
|
||||
inline __host__ __device__ uint3 operator+(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
inline __host__ __device__ void operator+=(uint3 &a, uint3 b)
|
||||
{
|
||||
a.x += b.x; a.y += b.y; a.z += b.z;
|
||||
}
|
||||
|
||||
// subtract
|
||||
inline __host__ __device__ uint3 operator-(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z);
|
||||
}
|
||||
|
||||
inline __host__ __device__ void operator-=(uint3 &a, uint3 b)
|
||||
{
|
||||
a.x -= b.x; a.y -= b.y; a.z -= b.z;
|
||||
}
|
||||
|
||||
// multiply
|
||||
inline __host__ __device__ uint3 operator*(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||
}
|
||||
inline __host__ __device__ uint3 operator*(uint3 a, uint s)
|
||||
{
|
||||
return make_uint3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ uint3 operator*(uint s, uint3 a)
|
||||
{
|
||||
return make_uint3(a.x * s, a.y * s, a.z * s);
|
||||
}
|
||||
inline __host__ __device__ void operator*=(uint3 &a, uint s)
|
||||
{
|
||||
a.x *= s; a.y *= s; a.z *= s;
|
||||
}
|
||||
|
||||
// divide
|
||||
inline __host__ __device__ uint3 operator/(uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||
}
|
||||
inline __host__ __device__ uint3 operator/(uint3 a, uint s)
|
||||
{
|
||||
return make_uint3(a.x / s, a.y / s, a.z / s);
|
||||
}
|
||||
inline __host__ __device__ uint3 operator/(uint s, uint3 a)
|
||||
{
|
||||
return make_uint3(a.x / s, a.y / s, a.z / s);
|
||||
}
|
||||
inline __host__ __device__ void operator/=(uint3 &a, uint s)
|
||||
{
|
||||
a.x /= s; a.y /= s; a.z /= s;
|
||||
}
|
||||
|
||||
// clamp
|
||||
inline __device__ __host__ uint clamp(uint f, uint a, uint b)
|
||||
{
|
||||
return max(a, min(f, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b)
|
||||
{
|
||||
return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
|
||||
}
|
||||
|
||||
inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b)
|
||||
{
|
||||
return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
|
||||
}
|
||||
|
||||
#endif
|
||||
31
src/include/diaphragm.h
Normal file
31
src/include/diaphragm.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* diaphragm.h
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __DIAPHRAGM_H__
|
||||
#define __DIAPHRAGM_H__
|
||||
|
||||
#include "wrapper.h"
|
||||
|
||||
aHole *readHoles(char *filename, Diaphragm *dia);
|
||||
char *My_mmap(char *filename, size_t *Mlen);
|
||||
|
||||
#endif // __DIAPHRAGM_H__
|
||||
187
src/include/mkHartmann.h
Normal file
187
src/include/mkHartmann.h
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* mkHartmann.h - main header file with common definitions
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef __MKHARTMANN_H__
|
||||
#define __MKHARTMANN_H__
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <features.h>
|
||||
#include <assert.h> // assert
|
||||
#include <stdlib.h> // malloc/free etc
|
||||
#include <stdio.h> // printf etc
|
||||
#include <stdint.h> // int types
|
||||
#include <stdarg.h> // vprintf
|
||||
#include <string.h> // memset etc
|
||||
#include <unistd.h> // file operations
|
||||
#include <libintl.h> // gettext
|
||||
#include <limits.h> // LONG_MAX
|
||||
#include <sys/time.h> // gettimeofday
|
||||
#include <sys/types.h> // open
|
||||
#include <sys/stat.h> // open
|
||||
#include <fcntl.h> // open
|
||||
#include <math.h> // floor & other math
|
||||
#include <err.h> // err
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h> // munmap
|
||||
#include <time.h> // time, ctime
|
||||
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON 1.19209E-07
|
||||
#endif
|
||||
|
||||
#ifndef GETTEXT_PACKAGE
|
||||
#define GETTEXT_PACKAGE "mkHartmann"
|
||||
#endif
|
||||
#ifndef PACKAGE_VERSION
|
||||
#define PACKAGE_VERSION "0.0.1"
|
||||
#endif
|
||||
#ifndef LOCALEDIR
|
||||
#define LOCALEDIR "/usr/share/locale/"
|
||||
#endif
|
||||
|
||||
#define _(String) gettext(String)
|
||||
#define gettext_noop(String) String
|
||||
#define N_(String) gettext_noop(String)
|
||||
|
||||
#define _U_ __attribute__((__unused__))
|
||||
|
||||
#ifndef THREAD_NUMBER
|
||||
#define THREAD_NUMBER 2
|
||||
#endif
|
||||
|
||||
#ifdef OMP
|
||||
#ifndef OMP_NUM_THREADS
|
||||
#define OMP_NUM_THREADS THREAD_NUMBER
|
||||
#endif
|
||||
#define Stringify(x) #x
|
||||
#define OMP_FOR(x) _Pragma(Stringify(omp parallel for x))
|
||||
#else
|
||||
#define OMP_FOR(x)
|
||||
#endif // OMP
|
||||
|
||||
extern int globErr;
|
||||
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)
|
||||
#define ERRX(...) do{globErr=0; _WARN(__VA_ARGS__); exit(-1);}while(0)
|
||||
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
|
||||
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
|
||||
|
||||
// debug mode, -DEBUG
|
||||
#ifdef EBUG
|
||||
#define FNAME() fprintf(stderr, "\n%s (%s, line %d)\n", __func__, __FILE__, __LINE__)
|
||||
#define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fprintf(stderr, "\n");} while(0)
|
||||
#else
|
||||
#define FNAME() do{}while(0)
|
||||
#define DBG(...) do{}while(0)
|
||||
#endif //EBUG
|
||||
|
||||
#define ALLOC(type, var, size) type * var = ((type *)my_alloc(size, sizeof(type)))
|
||||
#define MALLOC(type, size) ((type *)my_alloc(size, sizeof(type)))
|
||||
#define FREE(ptr) do{free(ptr); ptr = NULL;}while(0)
|
||||
|
||||
#ifndef EXTERN // file wasn't included from CUDA.cu
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#define RAD 57.2957795130823
|
||||
#define D2R(x) ((x) / RAD)
|
||||
#define R2D(x) ((x) * RAD)
|
||||
|
||||
// STRUCTURES definition
|
||||
|
||||
// bounding box
|
||||
typedef struct{
|
||||
float x0; // left border
|
||||
float y0; // lower border
|
||||
float w; // width
|
||||
float h; // height
|
||||
} BBox;
|
||||
|
||||
// mirror deviation parameters
|
||||
typedef struct{
|
||||
float *mirZ; // Z
|
||||
float *mirDX;// dZ/dX
|
||||
float *mirDY;// dZ/dY
|
||||
size_t mirWH;// size: mirWH x mirWH
|
||||
}mirDeviations;
|
||||
|
||||
// type of hole in diaphragm
|
||||
typedef enum{
|
||||
H_SQUARE // square hole
|
||||
,H_ELLIPSE // elliptic hole
|
||||
,H_UNDEF // error: can't define type
|
||||
} HoleType;
|
||||
|
||||
// hole in diaphragm
|
||||
typedef struct{
|
||||
BBox box; // bounding box of hole
|
||||
int type; // type, in case of round hole borders of box are tangents to hole
|
||||
} aHole;
|
||||
|
||||
// mirror mask for given diaphragm
|
||||
typedef struct{
|
||||
size_t WH; // size of mask: WH x WH
|
||||
uint16_t *data; // mask data
|
||||
}mirMask;
|
||||
|
||||
// diaphragm itself
|
||||
typedef struct{
|
||||
BBox box; // bounding box of diaphragm, must be a little larger of its contents
|
||||
aHole *holes; // array of holes
|
||||
int Nholes; // size of array
|
||||
float Z; // z-coordinate of diaphragm
|
||||
mirMask *mask;
|
||||
} Diaphragm;
|
||||
|
||||
// parameters of mirror
|
||||
typedef struct{
|
||||
float D; // diameter
|
||||
float F; // focus
|
||||
float Zincl; // inclination from Z axe (radians)
|
||||
float Aincl; // azimuth of inclination (radians)
|
||||
float objA; // azimuth of object (radians)
|
||||
float objZ; // zenith of object (radians)
|
||||
float foc; // Z-coordinate of light receiver
|
||||
Diaphragm *dia; // diaphragm or NULL
|
||||
} mirPar;
|
||||
|
||||
// functions for color output in tty & no-color in pipes
|
||||
EXTERN int (*red)(const char *fmt, ...);
|
||||
EXTERN int (*_WARN)(const char *fmt, ...);
|
||||
EXTERN int (*green)(const char *fmt, ...);
|
||||
void * my_alloc(size_t N, size_t S);
|
||||
|
||||
|
||||
#endif // __MKHARTMANN_H__
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* <===========================================================================>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
104
src/include/parceargs.h
Normal file
104
src/include/parceargs.h
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* parceargs.h - headers for parcing command line arguments
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef __PARCEARGS_H__
|
||||
#define __PARCEARGS_H__
|
||||
|
||||
#include <stdbool.h>// bool
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
// macro for argptr
|
||||
#define APTR(x) ((void*)x)
|
||||
|
||||
// if argptr is a function:
|
||||
typedef bool(*argfn)(void *arg, int N);
|
||||
|
||||
/*
|
||||
* type of getopt's argument
|
||||
* WARNING!
|
||||
* My function change value of flags by pointer, so if you want to use another type
|
||||
* make a latter conversion, example:
|
||||
* char charg;
|
||||
* int iarg;
|
||||
* myoption opts[] = {
|
||||
* {"value", 1, NULL, 'v', arg_int, &iarg, "char val"}, ..., end_option};
|
||||
* ..(parce args)..
|
||||
* charg = (char) iarg;
|
||||
*/
|
||||
typedef enum {
|
||||
arg_none = 0, // no arg
|
||||
arg_int, // integer
|
||||
arg_longlong, // long long
|
||||
arg_double, // double
|
||||
arg_float, // float
|
||||
arg_string, // char *
|
||||
arg_function // parce_args will run function `bool (*fn)(char *optarg, int N)`
|
||||
} argtype;
|
||||
|
||||
/*
|
||||
* Structure for getopt_long & help
|
||||
* BE CAREFUL: .argptr is pointer to data or pointer to function,
|
||||
* conversion depends on .type
|
||||
*
|
||||
* ATTENTION: string `help` prints through macro PRNT(), bu default it is gettext,
|
||||
* but you can redefine it before `#include "parceargs.h"`
|
||||
*
|
||||
* if arg is string, then value wil be strdup'ed like that:
|
||||
* char *str;
|
||||
* myoption opts[] = {{"string", 1, NULL, 's', arg_string, &str, "string val"}, ..., end_option};
|
||||
* *(opts[1].str) = strdup(optarg);
|
||||
* in other cases argptr should be address of some variable (or pointer to allocated memory)
|
||||
*
|
||||
* NON-NULL argptr should be written inside macro APTR(argptr) or directly: (void*)argptr
|
||||
*
|
||||
* !!!LAST VALUE OF ARRAY SHOULD BE `end_option` or ZEROS !!!
|
||||
*
|
||||
*/
|
||||
typedef struct{
|
||||
// these are from struct option:
|
||||
const char *name; // long option's name
|
||||
int has_arg; // 0 - no args, 1 - nesessary arg, 2 - optionally arg
|
||||
int *flag; // NULL to return val, pointer to int - to set its value of val (function returns 0)
|
||||
int val; // short opt name (if flag == NULL) or flag's value
|
||||
// and these are mine:
|
||||
argtype type; // type of argument
|
||||
void *argptr; // pointer to variable to assign optarg value or function `bool (*fn)(char *optarg, int N)`
|
||||
char *help; // help string which would be shown in function `showhelp` or NULL
|
||||
} myoption;
|
||||
|
||||
// last string of array (all zeros)
|
||||
#define end_option {0,0,0,0,0,0,0}
|
||||
|
||||
|
||||
extern const char *__progname;
|
||||
|
||||
void showhelp(int oindex, myoption *options);
|
||||
void parceargs(int *argc, char ***argv, myoption *options);
|
||||
void change_helpstring(char *s);
|
||||
|
||||
#endif // __PARCEARGS_H__
|
||||
42
src/include/saveimg.h
Normal file
42
src/include/saveimg.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* saveimg.h
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __SAVEIMG_H__
|
||||
#define __SAVEIMG_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "wrapper.h"
|
||||
|
||||
typedef uint8_t imtype;
|
||||
enum{
|
||||
IT_FITS = (imtype)(1),
|
||||
IT_PNG = (imtype)(1<<1),
|
||||
IT_JPEG = (imtype)(1<<2),
|
||||
IT_TIFF = (imtype)(1<<3)
|
||||
};
|
||||
|
||||
int writeimg(char *name, imtype t, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data);
|
||||
|
||||
char *createfilename(char* outfile, char* suffix);
|
||||
|
||||
#endif // __SAVEIMG_H__
|
||||
144
src/include/wrapper.h
Normal file
144
src/include/wrapper.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* wrapper.h - CPU/GPU wrapper
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef __WRAPPER_H__
|
||||
#define __WRAPPER_H__
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif // EXTERN
|
||||
|
||||
#include "mkHartmann.h"
|
||||
|
||||
static const size_t MB = 1024*1024; // convert bytes to MB
|
||||
|
||||
void noCUDA();
|
||||
void tryCUDA();
|
||||
void forceCUDA();
|
||||
int CUsuccess();
|
||||
#ifdef CUDA_FOUND
|
||||
#define CUDAavailable() 1
|
||||
#else
|
||||
#define CUDAavailable() 0
|
||||
#endif
|
||||
|
||||
double dtime();
|
||||
void getprops();
|
||||
EXTERN long throw_random_seed();
|
||||
EXTERN int fillImage(float *phX, float *phY, size_t ph_sz,
|
||||
float *image, size_t imW, size_t imH, BBox *imbox);
|
||||
|
||||
mirMask *makeDmask(Diaphragm *d, size_t minSz, mirPar *M, mirDeviations *D);
|
||||
void freeDmask(mirMask *m);
|
||||
|
||||
|
||||
#define Fn1(A,B) A(x1)
|
||||
#define Df1(A,B) A(B x1)
|
||||
#define Fn2(A,B,C) A(x1, x2)
|
||||
#define Df2(A,B,C) A(B x1, C x2)
|
||||
#define Fn3(A,B,C,D) A(x1, x2, x3)
|
||||
#define Df3(A,B,C,D) A(B x1, C x2, D x3)
|
||||
#define Fn4(A,B,C,D,E) A(x1, x2, x3, x4)
|
||||
#define Df4(A,B,C,D,E) A(B x1, C x2, D x3, E x4)
|
||||
#define Fn5(A,B,C,D,E,F) A(x1, x2, x3, x4, x5)
|
||||
#define Df5(A,B,C,D,E,F) A(B x1, C x2, D x3, E x4, F x5)
|
||||
#define Fn6(A,B,C,D,E,F,G) A(x1, x2, x3, x4, x5, x6)
|
||||
#define Df6(A,B,C,D,E,F,G) A(B x1, C x2, D x3, E x4, F x5, G x6)
|
||||
#define Fn7(A,B,C,D,E,F,G,H) A(x1, x2, x3, x4, x5, x6, x7)
|
||||
#define Df7(A,B,C,D,E,F,G,H) A(B x1, C x2, D x3, E x4, F x5, G x6, H x7)
|
||||
#define Fn8(A,B,C,D,E,F,G,H,I) A(x1, x2, x3, x4, x5, x6, x7, x8)
|
||||
#define Df8(A,B,C,D,E,F,G,H,I) A(B x1, C x2, D x3, E x4, F x5, G x6, H x7, I x8)
|
||||
#define Fn9(A,B,C,D,E,F,G,H,I,J) A(x1, x2, x3, x4, x5, x6, x7, x8, x9)
|
||||
#define Df9(A,B,C,D,E,F,G,H,I,J) A(B x1, C x2, D x3, E x4, F x5, G x6, H x7, I x8, J x9)
|
||||
#define Fn10(A,B,C,D,E,F,G,H,I,J,K) A(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)
|
||||
#define Df10(A,B,C,D,E,F,G,H,I,J,K) A(B x1, C x2, D x3, E x4, F x5, G x6, H x7, I x8, J x9, K x10)
|
||||
|
||||
#define DEF(N, ...) int Df ## N(__VA_ARGS__)
|
||||
#define CONCAT(A, B) A ## B
|
||||
#define FN(N, ...) Fn ## N(__VA_ARGS__)
|
||||
#define DF(N, ...) Df ## N(__VA_ARGS__)
|
||||
#define XFUNC(T, X) CONCAT(T, X)
|
||||
#define FUNC(T, ...) XFUNC(T, FN(__VA_ARGS__))
|
||||
#define DFUNC(T,...) EXTERN int XFUNC(T, DF(__VA_ARGS__))
|
||||
|
||||
#ifdef WRAPPER_C
|
||||
// even when using cuda in case of fail CUDA init use CPU
|
||||
static int Only_CPU =
|
||||
#ifdef CUDA_FOUND
|
||||
0
|
||||
#else
|
||||
1
|
||||
#endif
|
||||
;
|
||||
|
||||
static int CUnoerr, CUforce = 0;
|
||||
|
||||
EXTERN int CUgetprops();
|
||||
EXTERN int CUgetMEM(size_t memsz, size_t *Free, size_t *Total);
|
||||
EXTERN int CUallocaTest(size_t memsz);
|
||||
|
||||
#ifdef CUDA_FOUND
|
||||
#define SET_F(...) DEF(__VA_ARGS__){ \
|
||||
if(!Only_CPU){ CUnoerr = 1; \
|
||||
if(FUNC(CU, __VA_ARGS__)) return 1; \
|
||||
else CUnoerr = 0; \
|
||||
}if(!CUforce && FUNC(CPU, __VA_ARGS__)) return 1; \
|
||||
return 0; \
|
||||
}
|
||||
#else
|
||||
#define SET_F(...) DEF(__VA_ARGS__){ \
|
||||
if(FUNC(CPU, __VA_ARGS__)) return 1; \
|
||||
return 0; \
|
||||
}
|
||||
#endif // CUDA_FOUND
|
||||
#else
|
||||
#define SET_F(...)
|
||||
#endif // WRAPPER_C
|
||||
|
||||
#ifdef CPU_C // file included from CPU.c
|
||||
#define BOTH(...) DFUNC(CPU, __VA_ARGS__);
|
||||
//#pragma message "CPUC"
|
||||
#elif defined CUDA_CU //file included from CUDA.cu
|
||||
#define BOTH(...) DFUNC(CU, __VA_ARGS__);
|
||||
#elif defined WRAPPER_C // wrapper.c needs names of both wariants
|
||||
#ifndef CUDA_FOUND
|
||||
#define BOTH(...) DFUNC(CPU, __VA_ARGS__);
|
||||
#else
|
||||
#define BOTH(...) DFUNC(CU, __VA_ARGS__); DFUNC(CPU, __VA_ARGS__);
|
||||
#endif // CUDA_FOUND
|
||||
#else // file included from something else - just define a function
|
||||
#define BOTH(...) DFUNC(, __VA_ARGS__);
|
||||
#endif
|
||||
|
||||
#define DFN(...) BOTH(__VA_ARGS__) SET_F(__VA_ARGS__)
|
||||
|
||||
|
||||
DFN(3, fillrandarr, size_t, float *, float)
|
||||
|
||||
DFN(6, bicubic_interp, float *, float *, size_t, size_t, size_t, size_t)
|
||||
|
||||
DFN(4, mkmirDeviat, float *, size_t, float, mirDeviations *)
|
||||
|
||||
DFN(7, getPhotonXY, float *, float *, int, mirDeviations *, mirPar *, size_t, BBox *)
|
||||
|
||||
//DFN(7, fillImage, float *, float *, size_t, float *, size_t, size_t, BBox *)
|
||||
#endif // __WRAPPER_H__
|
||||
BIN
src/locale/ru/LC_MESSAGES/mkHartmann.mo
Normal file
BIN
src/locale/ru/LC_MESSAGES/mkHartmann.mo
Normal file
Binary file not shown.
304
src/locale/ru/messages.po
Normal file
304
src/locale/ru/messages.po
Normal file
@ -0,0 +1,304 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-02 17:54+0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: mkHartmann.c:168
|
||||
#, c-format
|
||||
msgid "Can't write to %s"
|
||||
msgstr ""
|
||||
|
||||
#. file not exist but some error occured
|
||||
#: mkHartmann.c:172 diaphragm.c:216
|
||||
#, c-format
|
||||
msgid "Can't stat %s"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:178
|
||||
msgid "No output filename given"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:185
|
||||
#, c-format
|
||||
msgid "Can't open file %s"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:199
|
||||
#, c-format
|
||||
msgid "Can't close file %s"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:229
|
||||
msgid "Wrong file: should be matrix of float data separated by spaces"
|
||||
msgstr ""
|
||||
|
||||
#. update old width counter
|
||||
#. check it
|
||||
#: mkHartmann.c:237
|
||||
msgid "All rows must contain equal number of columns"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:243
|
||||
msgid "Matrix must be square"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:254
|
||||
msgid "Input file was modified in runtime!"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:259
|
||||
#, c-format
|
||||
msgid "Error reading data: read %d numbers instaed of %d"
|
||||
msgstr ""
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÏÓÔÒÏÉÔØ ÍÁÔÒÉÃÕ ÓÌÕÞÁÊÎÙÈ ÞÉÓÅÌ"
|
||||
#: mkHartmann.c:316
|
||||
msgid "Can't build random matrix"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:323
|
||||
msgid "Can't build mirror dZ arrays"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:44
|
||||
msgid "Wrong value! Get non-number!\n"
|
||||
msgstr ""
|
||||
|
||||
#. nested arrays is error
|
||||
#: diaphragm.c:68
|
||||
msgid "Invalid file format! Found nested arrays!\n"
|
||||
msgstr ""
|
||||
|
||||
#. non-numerical data?
|
||||
#: diaphragm.c:74
|
||||
msgid "Invalid file format! Non-numerical data in array!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:95
|
||||
msgid "\"bbox\" must contain an array of four doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:112
|
||||
msgid "Error: NULL instead of aHole structure!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:130
|
||||
msgid "\"radius\" array must consist of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:135
|
||||
msgid "\"radius\" must be a number or an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:141
|
||||
msgid "\"center\" must contain an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:178
|
||||
msgid "Invalid holes array format!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:212
|
||||
msgid "No filename given!"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:214
|
||||
#, c-format
|
||||
msgid "Can't open %s for reading"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:219
|
||||
msgid "Mmap error for input"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:220
|
||||
msgid "Can't close mmap'ed file"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:251
|
||||
msgid ""
|
||||
"JSON file MUST contain floating point field \"Z\" or \"maskz\" with mask's "
|
||||
"coordinate"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:256
|
||||
msgid "Corrupted file: no holes found!"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:267
|
||||
msgid "Didn't find any holes in json file!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
#: wrapper.c:39 wrapper.c:48 wrapper.c:58
|
||||
msgid "Tool was compiled without CUDA support"
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
#: wrapper.c:74
|
||||
msgid "In computations will try to use GPU\n"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
#: wrapper.c:79
|
||||
msgid "Can't get properties"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:81
|
||||
msgid "Can't determine free memory"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:83
|
||||
msgid "Can't allocate memory"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
#: wrapper.c:99
|
||||
msgid "Error in CUDA initialisation!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
#: wrapper.c:103
|
||||
#, c-format
|
||||
msgid "MEMORY: free = "
|
||||
msgstr ""
|
||||
|
||||
#. / " ÓÕÍÍÁÒÎÁÑ = "
|
||||
#: wrapper.c:106
|
||||
#, c-format
|
||||
msgid " total= "
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
#: wrapper.c:112
|
||||
msgid "Will use only CPU in computations\n"
|
||||
msgstr ""
|
||||
|
||||
#. / "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
#: wrapper.c:120
|
||||
#, c-format
|
||||
msgid "Allocation test for 100MB of memory passed\n"
|
||||
msgstr ""
|
||||
|
||||
#. / "\n\n÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ"
|
||||
#: wrapper.c:123
|
||||
msgid ""
|
||||
"\n"
|
||||
"\n"
|
||||
"All tests succeed"
|
||||
msgstr ""
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÏÔËÒÙÔØ"
|
||||
#: wrapper.c:154
|
||||
msgid "Can't open"
|
||||
msgstr ""
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ"
|
||||
#: wrapper.c:159
|
||||
msgid "Can't read"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:77
|
||||
msgid ""
|
||||
"set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:Ao=ang:"
|
||||
"Zo=ang:C=num]\n"
|
||||
"\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like -10m13.4 !\n"
|
||||
"\t\tdiam - diameter of mirror\n"
|
||||
"\t\tfoc - mirror focus ratio\n"
|
||||
"\t\tZincl - inclination from Z axe\n"
|
||||
"\t\tAincl - azimuth of inclination\n"
|
||||
"\t\tAobj - azimuth of object\n"
|
||||
"\t\tZobj - zenith of object\n"
|
||||
"\t\tccd - Z-coordinate of light receiver"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:89
|
||||
msgid "show this help"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:90
|
||||
msgid "size of initial array of surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:91
|
||||
msgid "size of interpolated array of surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:92
|
||||
msgid "resulting image size"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:93
|
||||
msgid "amount of photons falled to one pixel of matrix by one iteration"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:95
|
||||
msgid "add random noice to mirror surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:96
|
||||
msgid "amplitude of random noice (default: 1e-8)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:97
|
||||
msgid "filename for mirror surface deviations (in microns!)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:98
|
||||
msgid "rewrite output file if exists"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:99
|
||||
msgid "save matrices to file arg"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:100
|
||||
msgid "print matrices on screen"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:101
|
||||
msgid "save intermediate results to images"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:102
|
||||
msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:119
|
||||
msgid "Wrong float number format!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:147
|
||||
msgid "Degrees should be less than 360"
|
||||
msgstr ""
|
||||
|
||||
#. wrong format
|
||||
#: cmdlnopts.c:193
|
||||
msgid "Wrong format: no value for keyword"
|
||||
msgstr ""
|
||||
|
||||
#. nothing found - wrong format
|
||||
#: cmdlnopts.c:213
|
||||
msgid "Bad keyword!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:294
|
||||
#, c-format
|
||||
msgid "Wrong format of image type: %c"
|
||||
msgstr ""
|
||||
305
src/locale/ru/ru.po
Normal file
305
src/locale/ru/ru.po
Normal file
@ -0,0 +1,305 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-02 16:58+0400\n"
|
||||
"PO-Revision-Date: 2013-01-14 18:49+0400\n"
|
||||
"Last-Translator: Edward V. Emelianov <eddy@sao.ru>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. / "\n\n÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ"
|
||||
#: wrapper.c:123
|
||||
#, fuzzy
|
||||
msgid "\n"
|
||||
"\n"
|
||||
"All tests succeed"
|
||||
msgstr "\n"
|
||||
"\n"
|
||||
"÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ\n"
|
||||
"\n"
|
||||
|
||||
#. / " ÓÕÍÍÁÒÎÁÑ = "
|
||||
#: wrapper.c:106
|
||||
#, c-format
|
||||
msgid " total= "
|
||||
msgstr " ÓÕÍÍÁÒÎÁÑ = "
|
||||
|
||||
#: diaphragm.c:95
|
||||
msgid "\"bbox\" must contain an array of four doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:141
|
||||
msgid "\"center\" must contain an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:130
|
||||
msgid "\"radius\" array must consist of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:135
|
||||
msgid "\"radius\" must be a number or an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#. update old width counter
|
||||
#. check it
|
||||
#: mkHartmann.c:237
|
||||
msgid "All rows must contain equal number of columns"
|
||||
msgstr ""
|
||||
|
||||
#. / "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
#: wrapper.c:120
|
||||
#, c-format
|
||||
msgid "Allocation test for 100MB of memory passed\n"
|
||||
msgstr "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
|
||||
#. nothing found - wrong format
|
||||
#: cmdlnopts.c:213
|
||||
msgid "Bad keyword!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:83
|
||||
msgid "Can't allocate memory"
|
||||
msgstr "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
|
||||
#: mkHartmann.c:323
|
||||
msgid "Can't build mirror dZ arrays"
|
||||
msgstr ""
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÏÓÔÒÏÉÔØ ÍÁÔÒÉÃÕ ÓÌÕÞÁÊÎÙÈ ÞÉÓÅÌ"
|
||||
#: mkHartmann.c:316
|
||||
msgid "Can't build random matrix"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:199
|
||||
#, c-format
|
||||
msgid "Can't close file %s"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:220
|
||||
msgid "Can't close mmap'ed file"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:81
|
||||
msgid "Can't determine free memory"
|
||||
msgstr "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
|
||||
#. / "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
#: wrapper.c:79
|
||||
msgid "Can't get properties"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÏÔËÒÙÔØ"
|
||||
#: wrapper.c:154
|
||||
#, fuzzy
|
||||
msgid "Can't open"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#: diaphragm.c:214
|
||||
#, c-format
|
||||
msgid "Can't open %s for reading"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:185
|
||||
#, fuzzy, c-format
|
||||
msgid "Can't open file %s"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ"
|
||||
#: wrapper.c:159
|
||||
msgid "Can't read"
|
||||
msgstr ""
|
||||
|
||||
#. file not exist but some error occured
|
||||
#: mkHartmann.c:172 diaphragm.c:216
|
||||
#, c-format
|
||||
msgid "Can't stat %s"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:168
|
||||
#, c-format
|
||||
msgid "Can't write to %s"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:256
|
||||
msgid "Corrupted file: no holes found!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:147
|
||||
msgid "Degrees should be less than 360"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:267
|
||||
msgid "Didn't find any holes in json file!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
#: wrapper.c:99
|
||||
msgid "Error in CUDA initialisation!"
|
||||
msgstr "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
|
||||
#: mkHartmann.c:259
|
||||
#, c-format
|
||||
msgid "Error reading data: read %d numbers instaed of %d"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:112
|
||||
msgid "Error: NULL instead of aHole structure!\n"
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
#: wrapper.c:74
|
||||
msgid "In computations will try to use GPU\n"
|
||||
msgstr "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
|
||||
#: mkHartmann.c:254
|
||||
msgid "Input file was modified in runtime!"
|
||||
msgstr ""
|
||||
|
||||
#. nested arrays is error
|
||||
#: diaphragm.c:68
|
||||
msgid "Invalid file format! Found nested arrays!\n"
|
||||
msgstr ""
|
||||
|
||||
#. non-numerical data?
|
||||
#: diaphragm.c:74
|
||||
msgid "Invalid file format! Non-numerical data in array!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:178
|
||||
msgid "Invalid holes array format!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:251
|
||||
msgid "JSON file MUST contain floating point field \"Z\" or \"maskz\" with "
|
||||
"mask's coordinate"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
#: wrapper.c:103
|
||||
#, c-format
|
||||
msgid "MEMORY: free = "
|
||||
msgstr "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
|
||||
#: mkHartmann.c:243
|
||||
msgid "Matrix must be square"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:219
|
||||
msgid "Mmap error for input"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:212
|
||||
msgid "No filename given!"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:178
|
||||
msgid "No output filename given"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
#: wrapper.c:39 wrapper.c:48 wrapper.c:58
|
||||
msgid "Tool was compiled without CUDA support"
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
#: wrapper.c:112
|
||||
msgid "Will use only CPU in computations\n"
|
||||
msgstr "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
|
||||
#: mkHartmann.c:229
|
||||
msgid "Wrong file: should be matrix of float data separated by spaces"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:119
|
||||
msgid "Wrong float number format!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:294
|
||||
#, c-format
|
||||
msgid "Wrong format of image type: %c"
|
||||
msgstr ""
|
||||
|
||||
#. wrong format
|
||||
#: cmdlnopts.c:193
|
||||
msgid "Wrong format: no value for keyword"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:44
|
||||
msgid "Wrong value! Get non-number!\n"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:95
|
||||
msgid "add random noice to mirror surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:93
|
||||
msgid "amount of photons falled to one pixel of matrix by one iteration"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:96
|
||||
msgid "amplitude of random noice (default: 1e-8)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:97
|
||||
msgid "filename for mirror surface deviations (in microns!)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:102
|
||||
msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:100
|
||||
msgid "print matrices on screen"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:92
|
||||
msgid "resulting image size"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:98
|
||||
msgid "rewrite output file if exists"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:101
|
||||
msgid "save intermediate results to images"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:99
|
||||
msgid "save matrices to file arg"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:77
|
||||
msgid "set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:"
|
||||
"Ao=ang:Zo=ang:C=num]\n"
|
||||
"\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like "
|
||||
"-10m13.4 !\n"
|
||||
"\t\tdiam - diameter of mirror\n"
|
||||
"\t\tfoc - mirror focus ratio\n"
|
||||
"\t\tZincl - inclination from Z axe\n"
|
||||
"\t\tAincl - azimuth of inclination\n"
|
||||
"\t\tAobj - azimuth of object\n"
|
||||
"\t\tZobj - zenith of object\n"
|
||||
"\t\tccd - Z-coordinate of light receiver"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:89
|
||||
msgid "show this help"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:90
|
||||
msgid "size of initial array of surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:91
|
||||
msgid "size of interpolated array of surface deviations"
|
||||
msgstr ""
|
||||
301
src/locale/ru/ru.po~
Normal file
301
src/locale/ru/ru.po~
Normal file
@ -0,0 +1,301 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-02 16:46+0400\n"
|
||||
"PO-Revision-Date: 2013-01-14 18:49+0400\n"
|
||||
"Last-Translator: Edward V. Emelianov <eddy@sao.ru>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: Russian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=koi8-r\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. / "\n\n÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ"
|
||||
#: wrapper.c:123
|
||||
#, fuzzy
|
||||
msgid "\n"
|
||||
"\n"
|
||||
"All tests succeed"
|
||||
msgstr "\n"
|
||||
"\n"
|
||||
"÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ\n"
|
||||
"\n"
|
||||
|
||||
#. / " ÓÕÍÍÁÒÎÁÑ = "
|
||||
#: wrapper.c:106
|
||||
#, c-format
|
||||
msgid " total= "
|
||||
msgstr " ÓÕÍÍÁÒÎÁÑ = "
|
||||
|
||||
#: diaphragm.c:95
|
||||
msgid "\"bbox\" must contain an array of four doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:141
|
||||
msgid "\"center\" must contain an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:130
|
||||
msgid "\"radius\" array must consist of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:135
|
||||
msgid "\"radius\" must be a number or an array of two doubles!\n"
|
||||
msgstr ""
|
||||
|
||||
#. update old width counter
|
||||
#. check it
|
||||
#: mkHartmann.c:237
|
||||
msgid "All rows must contain equal number of columns"
|
||||
msgstr ""
|
||||
|
||||
#. / "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
#: wrapper.c:120
|
||||
#, c-format
|
||||
msgid "Allocation test for 100MB of memory passed\n"
|
||||
msgstr "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
|
||||
#. nothing found - wrong format
|
||||
#: cmdlnopts.c:213
|
||||
msgid "Bad keyword!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:83
|
||||
msgid "Can't allocate memory"
|
||||
msgstr "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÏÓÔÒÏÉÔØ ÍÁÔÒÉÃÕ ÓÌÕÞÁÊÎÙÈ ÞÉÓÅÌ"
|
||||
#: mkHartmann.c:317
|
||||
msgid "Can't build random matrix"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:199
|
||||
#, c-format
|
||||
msgid "Can't close file %s"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:220
|
||||
msgid "Can't close mmap'ed file"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
#: wrapper.c:81
|
||||
msgid "Can't determine free memory"
|
||||
msgstr "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
|
||||
#. / "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
#: wrapper.c:79
|
||||
msgid "Can't get properties"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÏÔËÒÙÔØ"
|
||||
#: wrapper.c:154
|
||||
#, fuzzy
|
||||
msgid "Can't open"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#: diaphragm.c:214
|
||||
#, c-format
|
||||
msgid "Can't open %s for reading"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:185
|
||||
#, fuzzy, c-format
|
||||
msgid "Can't open file %s"
|
||||
msgstr "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
|
||||
#. / "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ"
|
||||
#: wrapper.c:159
|
||||
msgid "Can't read"
|
||||
msgstr ""
|
||||
|
||||
#. file not exist but some error occured
|
||||
#: mkHartmann.c:172 diaphragm.c:216
|
||||
#, c-format
|
||||
msgid "Can't stat %s"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:168
|
||||
#, c-format
|
||||
msgid "Can't write to %s"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:256
|
||||
msgid "Corrupted file: no holes found!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:147
|
||||
msgid "Degrees should be less than 360"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:267
|
||||
msgid "Didn't find any holes in json file!"
|
||||
msgstr ""
|
||||
|
||||
#. / "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
#: wrapper.c:99
|
||||
msgid "Error in CUDA initialisation!"
|
||||
msgstr "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
|
||||
#: mkHartmann.c:259
|
||||
#, c-format
|
||||
msgid "Error reading data: read %d numbers instaed of %d"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:112
|
||||
msgid "Error: NULL instead of aHole structure!\n"
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
#: wrapper.c:74
|
||||
msgid "In computations will try to use GPU\n"
|
||||
msgstr "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
|
||||
#: mkHartmann.c:254
|
||||
msgid "Input file was modified in runtime!"
|
||||
msgstr ""
|
||||
|
||||
#. nested arrays is error
|
||||
#: diaphragm.c:68
|
||||
msgid "Invalid file format! Found nested arrays!\n"
|
||||
msgstr ""
|
||||
|
||||
#. non-numerical data?
|
||||
#: diaphragm.c:74
|
||||
msgid "Invalid file format! Non-numerical data in array!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:178
|
||||
msgid "Invalid holes array format!\n"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:251
|
||||
msgid "JSON file MUST contain floating point field \"Z\" or \"maskz\" with "
|
||||
"mask's coordinate"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
#: wrapper.c:103
|
||||
#, c-format
|
||||
msgid "MEMORY: free = "
|
||||
msgstr "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
|
||||
#: mkHartmann.c:243
|
||||
msgid "Matrix must be square"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:219
|
||||
msgid "Mmap error for input"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:212
|
||||
msgid "No filename given!"
|
||||
msgstr ""
|
||||
|
||||
#: mkHartmann.c:178
|
||||
msgid "No output filename given"
|
||||
msgstr ""
|
||||
|
||||
#. / "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
#: wrapper.c:39 wrapper.c:48 wrapper.c:58
|
||||
msgid "Tool was compiled without CUDA support"
|
||||
msgstr ""
|
||||
|
||||
#. / "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
#: wrapper.c:112
|
||||
msgid "Will use only CPU in computations\n"
|
||||
msgstr "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
|
||||
#: mkHartmann.c:229
|
||||
msgid "Wrong file: should be matrix of float data separated by spaces"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:119
|
||||
msgid "Wrong float number format!"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:294
|
||||
#, c-format
|
||||
msgid "Wrong format of image type: %c"
|
||||
msgstr ""
|
||||
|
||||
#. wrong format
|
||||
#: cmdlnopts.c:193
|
||||
msgid "Wrong format: no value for keyword"
|
||||
msgstr ""
|
||||
|
||||
#: diaphragm.c:44
|
||||
msgid "Wrong value! Get non-number!\n"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:95
|
||||
msgid "add random noice to mirror surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:93
|
||||
msgid "amount of photons falled to one pixel of matrix by one iteration"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:96
|
||||
msgid "amplitude of random noice (default: 1e-8)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:97
|
||||
msgid "filename for mirror surface deviations (in microns!)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:102
|
||||
msgid "image type, arg=[jfpt] (Jpeg, Fits, Png, Tiff)"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:100
|
||||
msgid "print matrices on screen"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:92
|
||||
msgid "resulting image size"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:98
|
||||
msgid "rewrite output file if exists"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:101
|
||||
msgid "save intermediate results to images"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:99
|
||||
msgid "save matrices to file arg"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:77
|
||||
msgid "set mirror parameters, arg=[diam=num:foc=num:Zincl=ang:Aincl=ang:"
|
||||
"Ao=ang:Zo=ang:C=num]\n"
|
||||
"\t\t\tALL DEGREES ARE IN FORMAT [+-][DDd][MMm][SS.S] like "
|
||||
"-10m13.4 !\n"
|
||||
"\t\tdiam - diameter of mirror\n"
|
||||
"\t\tfoc - mirror focus ratio\n"
|
||||
"\t\tZincl - inclination from Z axe\n"
|
||||
"\t\tAincl - azimuth of inclination\n"
|
||||
"\t\tAobj - azimuth of object\n"
|
||||
"\t\tZobj - zenith of object\n"
|
||||
"\t\tccd - Z-coordinate of light receiver"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:89
|
||||
msgid "show this help"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:90
|
||||
msgid "size of initial array of surface deviations"
|
||||
msgstr ""
|
||||
|
||||
#: cmdlnopts.c:91
|
||||
msgid "size of interpolated array of surface deviations"
|
||||
msgstr ""
|
||||
2
src/locale/ru/update
Executable file
2
src/locale/ru/update
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
msgmerge -Uis ru.po messages.po
|
||||
446
src/mkHartmann.c
Normal file
446
src/mkHartmann.c
Normal file
@ -0,0 +1,446 @@
|
||||
/*
|
||||
* mkHartmann.c - main file for mkHartmann utilite produsing hartmanogramms
|
||||
* of BTA telescope
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "mkHartmann.h"
|
||||
#include "cmdlnopts.h"
|
||||
#include "wrapper.h"
|
||||
#include "saveimg.h"
|
||||
#include "diaphragm.h"
|
||||
|
||||
/*
|
||||
* Coloured messages output
|
||||
*/
|
||||
#define RED "\033[1;31;40m"
|
||||
#define GREEN "\033[1;32;40m"
|
||||
#define OLDCOLOR "\033[0;0;0m"
|
||||
|
||||
|
||||
int globErr = 0; // errno for WARN/ERR
|
||||
// pointers to coloured output printf
|
||||
int (*red)(const char *fmt, ...);
|
||||
int (*green)(const char *fmt, ...);
|
||||
int (*_WARN)(const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* format red / green messages
|
||||
* name: r_pr_, g_pr_
|
||||
* @param fmt ... - printf-like format
|
||||
* @return number of printed symbols
|
||||
*/
|
||||
int r_pr_(const char *fmt, ...){
|
||||
va_list ar; int i;
|
||||
printf(RED);
|
||||
va_start(ar, fmt);
|
||||
i = vprintf(fmt, ar);
|
||||
va_end(ar);
|
||||
printf(OLDCOLOR);
|
||||
return i;
|
||||
}
|
||||
int g_pr_(const char *fmt, ...){
|
||||
va_list ar; int i;
|
||||
printf(GREEN);
|
||||
va_start(ar, fmt);
|
||||
i = vprintf(fmt, ar);
|
||||
va_end(ar);
|
||||
printf(OLDCOLOR);
|
||||
return i;
|
||||
}
|
||||
/*
|
||||
* print red error/warning messages (if output is a tty)
|
||||
* @param fmt ... - printf-like format
|
||||
* @return number of printed symbols
|
||||
*/
|
||||
int r_WARN(const char *fmt, ...){
|
||||
va_list ar; int i = 1;
|
||||
fprintf(stderr, RED);
|
||||
va_start(ar, fmt);
|
||||
if(globErr){
|
||||
errno = globErr;
|
||||
vwarn(fmt, ar);
|
||||
errno = 0;
|
||||
globErr = 0;
|
||||
}else
|
||||
i = vfprintf(stderr, fmt, ar);
|
||||
va_end(ar);
|
||||
i++;
|
||||
fprintf(stderr, OLDCOLOR "\n");
|
||||
return i;
|
||||
}
|
||||
|
||||
const char stars[] = "****************************************";
|
||||
/*
|
||||
* notty variants of coloured printf
|
||||
* name: s_WARN, r_pr_notty
|
||||
* @param fmt ... - printf-like format
|
||||
* @return number of printed symbols
|
||||
*/
|
||||
int s_WARN(const char *fmt, ...){
|
||||
va_list ar; int i;
|
||||
i = fprintf(stderr, "\n%s\n", stars);
|
||||
va_start(ar, fmt);
|
||||
if(globErr){
|
||||
errno = globErr;
|
||||
vwarn(fmt, ar);
|
||||
errno = 0;
|
||||
globErr = 0;
|
||||
}else
|
||||
i = +vfprintf(stderr, fmt, ar);
|
||||
va_end(ar);
|
||||
i += fprintf(stderr, "\n%s\n", stars);
|
||||
i += fprintf(stderr, "\n");
|
||||
return i;
|
||||
}
|
||||
int r_pr_notty(const char *fmt, ...){
|
||||
va_list ar; int i;
|
||||
i = printf("\n%s\n", stars);
|
||||
va_start(ar, fmt);
|
||||
i += vprintf(fmt, ar);
|
||||
va_end(ar);
|
||||
i += printf("\n%s\n", stars);
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* safe memory allocation for macro ALLOC
|
||||
* @param N - number of elements to allocate
|
||||
* @param S - size of single element (typically sizeof)
|
||||
* @return pointer to allocated memory area
|
||||
*/
|
||||
void *my_alloc(size_t N, size_t S){
|
||||
void *p = calloc(N, S);
|
||||
if(!p) ERR("malloc");
|
||||
//assert(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *outpfile = NULL; // filename for data output in octave text format
|
||||
int printDebug = 0; // print tab
|
||||
bool firstRun = TRUE; // first run: create new file
|
||||
/**
|
||||
* Print tabular on screen (if outpfile == NULL) or to outpfile
|
||||
* in octave text format
|
||||
* Function run only if printDebug == TRUE or outpfile != NULL
|
||||
*
|
||||
* @param W, H (i) - matrix width & height
|
||||
* @param data - data to print
|
||||
* @param mask - format to print (if on screen)
|
||||
* @param comment -
|
||||
* @return
|
||||
*/
|
||||
void printTAB(size_t W, size_t H, float *data, char *mask, char *comment){
|
||||
size_t x,y;
|
||||
if(!printDebug && !outpfile) return; // don't print debug info if no flag debug &/| outpfile
|
||||
if(!outpfile){ // simply print to stdout
|
||||
if(comment) printf("%s\n", comment);
|
||||
if(mask) printf("All units *1e-6\n");
|
||||
for(y = 0; y < H; y++){
|
||||
for(x = 0; x < W; x++){
|
||||
float d = data[H*(H-y-1) + x];
|
||||
mask ? printf(mask, d*1e6) : printf("%6g ", d);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// print to file
|
||||
struct stat statbuf;
|
||||
FILE *f = NULL;
|
||||
#define PR(...) do{if(fprintf(f, __VA_ARGS__) < 0) ERR(_("Can't write to %s"), outpfile);}while(0)
|
||||
if(firstRun){
|
||||
if(stat(outpfile, &statbuf)){
|
||||
if(ENOENT != errno) // file not exist but some error occured
|
||||
ERR(_("Can't stat %s"), outpfile);
|
||||
// OK, file not exist: use its name
|
||||
}else{ // file exists, create new name
|
||||
outpfile = createfilename(outpfile, NULL); // create new file name
|
||||
}
|
||||
firstRun = FALSE;
|
||||
if(!outpfile) ERRX(_("No output filename given"));
|
||||
f = fopen(outpfile, "w"); // create or truncate
|
||||
time_t T = time(NULL);
|
||||
PR("# Created by %s, %s\n", __progname, ctime(&T)); // add header
|
||||
}else{ // simply open file for adding info
|
||||
f = fopen(outpfile, "a");
|
||||
}
|
||||
if(!f) ERR(_("Can't open file %s"), outpfile);
|
||||
// print standard octave header for matrix
|
||||
if(comment) PR("# name: %s\n", comment);
|
||||
else PR("# name: tmp_%ju\n", (uintmax_t)time(NULL)); // or create temporary name
|
||||
PR("# type: matrix\n# rows: %zd\n# columns: %zd\n", H, W); // dimentions
|
||||
// now put out matrix itself (upside down - for octave/matlab)
|
||||
for(y = 0; y < H; y++){
|
||||
for(x = 0; x < W; x++){
|
||||
PR(" %g", *data++);
|
||||
}
|
||||
PR("\n");
|
||||
}
|
||||
PR("\n\n");
|
||||
#undef PR
|
||||
if(fclose(f)) ERR(_("Can't close file %s"), outpfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read array with deviations from file
|
||||
* if filename is NULL it will just generate zeros (Size x Size)
|
||||
* ALL DEVIATIONS in file are IN MICROMETERS!!!
|
||||
*
|
||||
* @param filename (i) - name of file or NULL for zeros
|
||||
* @param Size (io) - size of output square array
|
||||
* @return allocated array
|
||||
*/
|
||||
float *read_deviations(char *filename, size_t *Size){
|
||||
float *ret = NULL;
|
||||
int W = 0, W0 = 0, H0 = 0, i;
|
||||
size_t Mlen;
|
||||
char *Mem = NULL, *endptr, *ptr;
|
||||
if(!filename){
|
||||
assert(Size);
|
||||
ret = MALLOC(float, (*Size) * (*Size)); // allocate matrix with given size
|
||||
assert(ret);
|
||||
return ret;
|
||||
}
|
||||
// there was filename given: try to read data from it
|
||||
Mem = My_mmap(filename, &Mlen); // from diaphragm.c
|
||||
ptr = Mem;
|
||||
do{
|
||||
errno = 0;
|
||||
strtof(ptr, &endptr);
|
||||
if(errno || (endptr == ptr && *ptr))
|
||||
ERRX(_("Wrong file: should be matrix of float data separated by spaces"));
|
||||
W++;
|
||||
if(endptr >= Mem + Mlen) break; // eptr out of range - EOF?
|
||||
if(*endptr == '\n'){
|
||||
H0++;
|
||||
ptr = endptr + 1;
|
||||
if(!W0) W0 = W; // update old width counter
|
||||
else if(W != W0) // check it
|
||||
ERRX(_("All rows must contain equal number of columns"));
|
||||
W = 0;
|
||||
}else ptr = endptr;
|
||||
}while(endptr && endptr < Mem + Mlen);
|
||||
if(W > 1) H0++; // increase number of rows if there's no trailing '\n' in last line
|
||||
if(W0 != H0)
|
||||
ERRX(_("Matrix must be square"));
|
||||
*Size = W0;
|
||||
DBG("here");
|
||||
ret = MALLOC(float, W0*W0);
|
||||
DBG("there");
|
||||
ptr = Mem;
|
||||
for(i = 0, H0 = 0; H0 < W0; H0++)
|
||||
for(W = 0; W < W0; W++, i++){
|
||||
DBG("%d ", i);
|
||||
ret[W0*(W0-H0-1) + W] = strtof(ptr, &endptr) * 1e-6;
|
||||
if(errno || (endptr == ptr && *ptr) || endptr >= Mem + Mlen)
|
||||
ERRX(_("Input file was modified in runtime!"));
|
||||
ptr = endptr;
|
||||
}
|
||||
W0 *= W0;
|
||||
if(i != W0)
|
||||
ERRX(_("Error reading data: read %d numbers instaed of %d"), W-1, W0);
|
||||
munmap(Mem, Mlen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int save_images = 0;
|
||||
/*
|
||||
* N ph per pix of mask TIME, s
|
||||
* // 29400 non-zero pts in mask
|
||||
* 10000 50
|
||||
* 50000 73
|
||||
* 100000 102
|
||||
* 200000 160
|
||||
* 500000 303
|
||||
* 1000000 556
|
||||
* 2000000 1128
|
||||
* 5000000 2541
|
||||
* 10000000 4826
|
||||
*/
|
||||
int main(int argc, char **argv){
|
||||
glob_pars *G = NULL; // default parameters see in cmdlnopts.c
|
||||
mirPar *M = NULL; // default mirror parameters
|
||||
int x, y _U_;
|
||||
// setup coloured output
|
||||
if(isatty(STDOUT_FILENO)){ // make color output in tty
|
||||
red = r_pr_; green = g_pr_;
|
||||
}else{ // no colors in case of pipe
|
||||
red = r_pr_notty; green = printf;
|
||||
}
|
||||
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
|
||||
else _WARN = s_WARN;
|
||||
// Setup locale
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
||||
textdomain(GETTEXT_PACKAGE);
|
||||
G = parce_args(argc, argv);
|
||||
M = G->Mirror;
|
||||
// Run simple initialisation of CUDA and/or memory test
|
||||
getprops();
|
||||
size_t S0 = G->S_dev, S1 = G->S_interp, Sim = G->S_image, N_phot = G->N_phot;
|
||||
size_t masksize = S1 * S1;
|
||||
// type of image to save: fits, png, jpeg or tiff
|
||||
imtype imt = G->it;
|
||||
// bounding box of mirror
|
||||
BBox box;
|
||||
box.x0 = box.y0 = -M->D/2; box.w = box.h = M->D;
|
||||
float *idata = read_deviations(G->dev_filename, &S0);
|
||||
printTAB(S0, S0, idata, "%5.2f ", "input_deviations");
|
||||
G->S_dev = S0; // update size
|
||||
// memory allocation
|
||||
ALLOC(float, mirZ, masksize); // mirror Z coordinate
|
||||
ALLOC(float, mirDX, masksize); // projections of normale to mirror
|
||||
ALLOC(float, mirDY, masksize);
|
||||
if(G->randMask || G->randAmp != Gdefault.randAmp){ // add random numbers to mask
|
||||
if(!fillrandarr(S0*S0, idata, G->randAmp))
|
||||
/// "îÅ ÍÏÇÕ ÐÏÓÔÒÏÉÔØ ÍÁÔÒÉÃÕ ÓÌÕÞÁÊÎÙÈ ÞÉÓÅÌ"
|
||||
ERR(_("Can't build random matrix"));
|
||||
}
|
||||
// initialize structure of mirror deviations
|
||||
mirDeviations mD;
|
||||
mD.mirZ = mirZ; mD.mirDX = mirDX; mD.mirDY = mirDY;
|
||||
mD.mirWH = S1;
|
||||
if(!mkmirDeviat(idata, S0, M->D, &mD))
|
||||
ERRX(_("Can't build mirror dZ arrays"));
|
||||
if(save_images) writeimg("interp_deviations", imt, S1, S1, &box, M, mirZ);
|
||||
printTAB(S1, S1, mirZ, "%5.3f ", "interpolated_deviations");
|
||||
printTAB(S1, S1, mirDX, "%5.2f ", "dev_dZdX");
|
||||
printTAB(S1, S1, mirDY, "%5.2f ", "dev_dZdY");
|
||||
|
||||
/*aHole holes[3] = {
|
||||
{{-0.35, -0.35, 0.1, 0.1}, H_ELLIPSE},
|
||||
{{-0.2, 0.2, 0.7, 0.4}, H_ELLIPSE},
|
||||
{{-0.1,-0.45,0.6,0.6}, H_ELLIPSE}}; */
|
||||
|
||||
// Hartmann mask
|
||||
Diaphragm dia; //{{-0.5, -0.5, 1., 1.}, NULL, 0, 20., NULL};
|
||||
mirMask *mask;
|
||||
readHoles("holes.json", &dia);
|
||||
#ifdef EBUG
|
||||
green("Dia: ");
|
||||
printf("(%g, %g, %g, %g); %d holes, Z = %g\n", dia.box.x0, dia.box.y0,
|
||||
dia.box.w, dia.box.h, dia.Nholes, dia.Z);
|
||||
#endif
|
||||
if(!(mask = makeDmask(&dia, 128, M, &mD))) ERR("Can't make dmask!");
|
||||
M->dia = &dia;
|
||||
if(save_images){
|
||||
int S = (int)dia.mask->WH, S2=S*S;
|
||||
float *dm = MALLOC(float, S2);
|
||||
for(x=0; x<S2; x++) dm[x] = (float)dia.mask->data[x];
|
||||
writeimg("mirror_mask", imt, S, S, NULL, M, dm);
|
||||
free(dm);
|
||||
}
|
||||
// coordinates of photons
|
||||
ALLOC(float, xout, N_phot);
|
||||
ALLOC(float, yout, N_phot);
|
||||
// resulting image
|
||||
ALLOC(float, image, Sim*Sim);
|
||||
/*
|
||||
//for(int i = 0; i < 100; i++){
|
||||
box.x0 = -3.; box.y0 = -3.; box.w = 6.; box.h = 6.;
|
||||
if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box))
|
||||
ERR("Can't build photon map");
|
||||
box.x0 = -15e-3; box.y0 = -15e-3; box.w = 30e-3; box.h = 30e-3;
|
||||
//box.x0 = -5e-3; box.y0 = .8365; box.w = 10e-3; box.h = 10e-3;
|
||||
if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &box))
|
||||
ERR("Can't fill output image");
|
||||
//}
|
||||
writeimg("image", imt, Sim, Sim, &box, M, image);
|
||||
FREE(xout); FREE(yout); FREE(image);
|
||||
*/
|
||||
// CCD bounding box
|
||||
BBox CCD = {-15e-3, -15e-3, 30e-3, 30e-3};
|
||||
for(x = 0; x < 100; x++){
|
||||
if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box))
|
||||
ERR("Can't build photon map");
|
||||
if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &CCD))
|
||||
ERR("Can't fill output image");
|
||||
}
|
||||
/* int S = mask->WH;
|
||||
double R = M->D / 2., scale = M->D / (double)S;
|
||||
uint16_t *dptr = mask->data;
|
||||
box.w = box.h = scale;
|
||||
// check mask's pixels & throw photons to holes
|
||||
for(y = 0; y < S; y++){
|
||||
for(x = 0; x < S; x++, dptr++){
|
||||
if(!*dptr) continue;
|
||||
DBG("x = %d, Y=%d\n", x,y);
|
||||
box.x0 = -R + scale*(double)x;
|
||||
box.y0 = -R + scale*(double)y;
|
||||
if(!getPhotonXY(xout, yout, 1, &mD, M, N_phot, &box))
|
||||
ERR("Can't build photon map");
|
||||
if(!fillImage(xout, yout, N_phot, image, Sim, Sim, &CCD))
|
||||
ERR("Can't fill output image");
|
||||
}
|
||||
}
|
||||
*/
|
||||
writeimg("image", imt, Sim, Sim, &CCD, M, image);
|
||||
FREE(xout); FREE(yout); FREE(image);
|
||||
// if rand() is good, amount of photons on image should be 785398 on every 1000000
|
||||
//printTAB(Sim, Sim, image, NULL, "\n\nResulting image:");
|
||||
/* for(x = 0; x < N_phot; x++)
|
||||
if(fabs(xout[x]) < M->D/2. && fabs(yout[x]) < M->D/2.)
|
||||
printf("photon #%4d:\t\t(%g, %g)\n", x, xout[x]*1e6, yout[x]*1e6);*/
|
||||
|
||||
/* FILE *F = fopen("TESTs", "w");
|
||||
if(!F) ERR("Can't open");
|
||||
fprintf(F,"S1\tGPU\t\tCPU\n");
|
||||
|
||||
|
||||
for(S1 = 100; ; S1 += S1*drand48()){
|
||||
float *odata = my_alloc(S1*S1, sizeof(float));
|
||||
double t0;
|
||||
fprintf(F,"%zd", S1);
|
||||
forceCUDA();
|
||||
*/
|
||||
/* int x, y; float *ptr = idata;
|
||||
printf("Original array:\n");
|
||||
for(y = 0; y < 5; y++){
|
||||
for(x = 0; x < 5; x++){
|
||||
*ptr *= 2.;
|
||||
*ptr += x;
|
||||
printf("%4.3f ", (*ptr++));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
t0 = dtime();
|
||||
if(!bicubic_interp(odata, idata, S1,S1, S0,S0)) fprintf(F,"\tnan");
|
||||
else fprintf(F,"\t%g", dtime() - t0);
|
||||
|
||||
printf("Enlarged array:\n");
|
||||
ptr = odata;
|
||||
for(y = 0; y < 20; y++){
|
||||
for(x = 0; x < 20; x++)
|
||||
printf("%4.3f ", (*ptr++));
|
||||
printf("\n");
|
||||
}
|
||||
*
|
||||
noCUDA();
|
||||
t0 = dtime();
|
||||
/// "îÅ ÍÏÇÕ ÐÏÓÔÒÏÉÔØ ÉÎÔÅÒÐÏÌÑÃÉÀ"
|
||||
if(!bicubic_interp(odata, idata, S1,S1, S0,S0)) ERR(_("Can't do interpolation"));
|
||||
fprintf(F,"\t%g\n", dtime() - t0);
|
||||
fflush(F);
|
||||
free(odata);
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
316
src/parceargs.c
Normal file
316
src/parceargs.c
Normal file
@ -0,0 +1,316 @@
|
||||
/*
|
||||
* parceargs.c - parcing command line arguments & print help
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h> // DBG
|
||||
#include <getopt.h> // getopt_long
|
||||
#include <stdlib.h> // calloc, exit, strtoll
|
||||
#include <assert.h> // assert
|
||||
#include <string.h> // strdup, strchr, strlen
|
||||
#include <limits.h> // INT_MAX & so on
|
||||
#include <libintl.h>// gettext
|
||||
#include <ctype.h> // isalpha
|
||||
#include "parceargs.h"
|
||||
|
||||
#ifdef EBUG
|
||||
#define DBG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DBG(...)
|
||||
#endif
|
||||
|
||||
// macro to print help messages
|
||||
#ifndef PRNT
|
||||
#define PRNT(x) gettext(x)
|
||||
#endif
|
||||
|
||||
char *helpstring = "%s\n";
|
||||
|
||||
/**
|
||||
* Change standard help header
|
||||
* MAY consist ONE "%s" for progname
|
||||
* @param str (i) - new format
|
||||
*/
|
||||
|
||||
void change_helpstring(char *s){
|
||||
int pcount = 0, scount = 0;
|
||||
char *str = s;
|
||||
// check `helpstring` and set it to default in case of error
|
||||
for(; pcount < 2; str += 2){
|
||||
if(!(str = strchr(str, '%'))) break;
|
||||
if(str[1] != '%') pcount++; // increment '%' counter if it isn't "%%"
|
||||
else{
|
||||
str += 2; // pass next '%'
|
||||
continue;
|
||||
}
|
||||
if(str[1] == 's') scount++; // increment "%s" counter
|
||||
};
|
||||
DBG("pc: %d, sc: %d\n", pcount, scount);
|
||||
if(pcount > 1 || pcount != scount){ // amount of pcount and/or scount wrong
|
||||
fprintf(stderr, "Wrong helpstring!\n");
|
||||
exit(-1);
|
||||
}
|
||||
helpstring = s;
|
||||
DBG("hs: %s\n", helpstring);
|
||||
}
|
||||
|
||||
/**
|
||||
* Carefull atoll/atoi
|
||||
* @param num (o) - returning value (or NULL if you wish only check number) - allocated by user
|
||||
* @param str (i) - string with number must not be NULL
|
||||
* @param t (i) - T_INT for integer or T_LLONG for long long (if argtype would be wided, may add more)
|
||||
* @return TRUE if conversion sone without errors, FALSE otherwise
|
||||
*/
|
||||
bool myatoll(void *num, char *str, argtype t){
|
||||
long long tmp, *llptr;
|
||||
int *iptr;
|
||||
char *endptr;
|
||||
assert(str);
|
||||
assert(num);
|
||||
tmp = strtoll(str, &endptr, 0);
|
||||
if(endptr == str || *str == '\0' || *endptr != '\0')
|
||||
return FALSE;
|
||||
switch(t){
|
||||
case arg_longlong:
|
||||
llptr = (long long*) num;
|
||||
*llptr = tmp;
|
||||
break;
|
||||
case arg_int:
|
||||
default:
|
||||
if(tmp < INT_MIN || tmp > INT_MAX){
|
||||
fprintf(stderr, "Integer out of range\n");
|
||||
return FALSE;
|
||||
}
|
||||
iptr = (int*)num;
|
||||
*iptr = (int)tmp;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// the same as myatoll but for double
|
||||
// There's no NAN & INF checking here (what if they would be needed?)
|
||||
bool myatod(void *num, const char *str, argtype t){
|
||||
double tmp, *dptr;
|
||||
float *fptr;
|
||||
char *endptr;
|
||||
assert(str);
|
||||
tmp = strtod(str, &endptr);
|
||||
if(endptr == str || *str == '\0' || *endptr != '\0')
|
||||
return FALSE;
|
||||
switch(t){
|
||||
case arg_double:
|
||||
dptr = (double *) num;
|
||||
*dptr = tmp;
|
||||
break;
|
||||
case arg_float:
|
||||
default:
|
||||
fptr = (float *) num;
|
||||
*fptr = (float)tmp;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get index of current option in array options
|
||||
* @param opt (i) - returning val of getopt_long
|
||||
* @param options (i) - array of options
|
||||
* @return index in array
|
||||
*/
|
||||
int get_optind(int opt, myoption *options){
|
||||
int oind;
|
||||
myoption *opts = options;
|
||||
assert(opts);
|
||||
for(oind = 0; opts->name && opts->val != opt; oind++, opts++);
|
||||
if(!opts->name || opts->val != opt) // no such parameter
|
||||
showhelp(-1, options);
|
||||
return oind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parce command line arguments
|
||||
* ! If arg is string, then value will be strdup'ed!
|
||||
*
|
||||
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
||||
* @param argv (io) - address of argv of main(), return pointer to argv stay after `getopt`
|
||||
* BE CAREFUL! if you wanna use full argc & argv, save their original values before
|
||||
* calling this function
|
||||
* @param options (i) - array of `myoption` for arguments parcing
|
||||
*
|
||||
* @exit: in case of error this function show help & make `exit(-1)`
|
||||
*/
|
||||
void parceargs(int *argc, char ***argv, myoption *options){
|
||||
char *short_options, *soptr;
|
||||
struct option *long_options, *loptr;
|
||||
size_t optsize, i;
|
||||
myoption *opts = options;
|
||||
// check whether there is at least one options
|
||||
assert(opts);
|
||||
assert(opts[0].name);
|
||||
// first we count how much values are in opts
|
||||
for(optsize = 0; opts->name; optsize++, opts++);
|
||||
// now we can allocate memory
|
||||
short_options = calloc(optsize * 3 + 1, 1); // multiply by three for '::' in case of args in opts
|
||||
long_options = calloc(optsize + 1, sizeof(struct option));
|
||||
opts = options; loptr = long_options; soptr = short_options;
|
||||
// fill short/long parameters and make a simple checking
|
||||
for(i = 0; i < optsize; i++, loptr++, opts++){
|
||||
// check
|
||||
assert(opts->name); // check name
|
||||
if(opts->has_arg){
|
||||
assert(opts->type != arg_none); // check error with arg type
|
||||
assert(opts->argptr); // check pointer
|
||||
}
|
||||
if(opts->type != arg_none) // if there is a flag without arg, check its pointer
|
||||
assert(opts->argptr);
|
||||
// fill long_options
|
||||
// don't do memcmp: what if there would be different alignment?
|
||||
loptr->name = opts->name;
|
||||
loptr->has_arg = opts->has_arg;
|
||||
loptr->flag = opts->flag;
|
||||
loptr->val = opts->val;
|
||||
// fill short options if they are:
|
||||
if(!opts->flag){
|
||||
*soptr++ = opts->val;
|
||||
if(opts->has_arg) // add ':' if option has required argument
|
||||
*soptr++ = ':';
|
||||
if(opts->has_arg == 2) // add '::' if option has optional argument
|
||||
*soptr++ = ':';
|
||||
}
|
||||
}
|
||||
// now we have both long_options & short_options and can parse `getopt_long`
|
||||
while(1){
|
||||
int opt;
|
||||
int oindex = 0, optind = 0; // oindex - number of option in argv, optind - number in options[]
|
||||
if((opt = getopt_long(*argc, *argv, short_options, long_options, &oindex)) == -1) break;
|
||||
if(opt == '?'){
|
||||
opt = optopt;
|
||||
optind = get_optind(opt, options);
|
||||
if(options[optind].has_arg == 1) showhelp(optind, options); // need argument
|
||||
}
|
||||
else{
|
||||
if(opt == 0 || oindex > 0) optind = oindex;
|
||||
else optind = get_optind(opt, options);
|
||||
}
|
||||
opts = &options[optind];
|
||||
DBG ("\n*******\noption %s (oindex = %d / optind = %d)", options[optind].name, oindex, optind);
|
||||
if(optarg) DBG (" with arg %s", optarg);
|
||||
DBG ("\n");
|
||||
if(opt == 0 && opts->has_arg == 0) continue; // only long option changing integer flag
|
||||
DBG("opt = %c, arg type: ", opt);
|
||||
// now check option
|
||||
if(opts->has_arg == 1) assert(optarg);
|
||||
bool result = TRUE;
|
||||
// even if there is no argument, but argptr != NULL, think that optarg = "1"
|
||||
if(!optarg) optarg = "1";
|
||||
switch(opts->type){
|
||||
default:
|
||||
case arg_none:
|
||||
DBG("none\n");
|
||||
break;
|
||||
case arg_int:
|
||||
DBG("integer\n");
|
||||
result = myatoll(opts->argptr, optarg, arg_int);
|
||||
break;
|
||||
case arg_longlong:
|
||||
DBG("long long\n");
|
||||
result = myatoll(opts->argptr, optarg, arg_longlong);
|
||||
break;
|
||||
case arg_double:
|
||||
DBG("double\n");
|
||||
result = myatod(opts->argptr, optarg, arg_double);
|
||||
break;
|
||||
case arg_float:
|
||||
DBG("double\n");
|
||||
result = myatod(opts->argptr, optarg, arg_float);
|
||||
break;
|
||||
case arg_string:
|
||||
DBG("string\n");
|
||||
result = (*((char **)opts->argptr) = strdup(optarg));
|
||||
break;
|
||||
case arg_function:
|
||||
DBG("function\n");
|
||||
result = ((argfn)opts->argptr)(optarg, optind);
|
||||
break;
|
||||
}
|
||||
if(!result){
|
||||
DBG("OOOPS! Error in result\n");
|
||||
showhelp(optind, options);
|
||||
}
|
||||
}
|
||||
*argc -= optind;
|
||||
*argv += optind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show help information based on myoption->help values
|
||||
* @param oindex (i) - if non-negative, show only help by myoption[oindex].help
|
||||
* @param options (i) - array of `myoption`
|
||||
*
|
||||
* @exit: run `exit(-1)` !!!
|
||||
*/
|
||||
void showhelp(int oindex, myoption *options){
|
||||
// ATTENTION: string `help` prints through macro PRNT(), bu default it is gettext,
|
||||
// but you can redefine it before `#include "parceargs.h"`
|
||||
int max_opt_len = 0; // max len of options substring - for right indentation
|
||||
const int bufsz = 255;
|
||||
char buf[bufsz+1];
|
||||
myoption *opts = options;
|
||||
assert(opts);
|
||||
assert(opts[0].name); // check whether there is at least one options
|
||||
if(oindex > -1){ // print only one message
|
||||
opts = &options[oindex];
|
||||
printf(" ");
|
||||
if(!opts->flag && isalpha(opts->val)) printf("-%c, ", opts->val);
|
||||
printf("--%s", opts->name);
|
||||
if(opts->has_arg == 1) printf("=arg");
|
||||
else if(opts->has_arg == 2) printf("[=arg]");
|
||||
printf(" %s\n", PRNT(opts->help));
|
||||
exit(-1);
|
||||
}
|
||||
// header, by default is just "progname\n"
|
||||
printf("\n");
|
||||
if(strstr(helpstring, "%s")) // print progname
|
||||
printf(helpstring, __progname);
|
||||
else // only text
|
||||
printf("%s", helpstring);
|
||||
printf("\n");
|
||||
// count max_opt_len
|
||||
do{
|
||||
int L = strlen(opts->name);
|
||||
if(max_opt_len < L) max_opt_len = L;
|
||||
}while((++opts)->name);
|
||||
max_opt_len += 14; // format: '-S , --long[=arg]' - get addition 13 symbols
|
||||
opts = options;
|
||||
// Now print all help
|
||||
do{
|
||||
int p = sprintf(buf, " "); // a little indent
|
||||
if(!opts->flag && isalpha(opts->val)) // .val is short argument
|
||||
p += snprintf(buf+p, bufsz-p, "-%c, ", opts->val);
|
||||
p += snprintf(buf+p, bufsz-p, "--%s", opts->name);
|
||||
if(opts->has_arg == 1) // required argument
|
||||
p += snprintf(buf+p, bufsz-p, "=arg");
|
||||
else if(opts->has_arg == 2) // optional argument
|
||||
p += snprintf(buf+p, bufsz-p, "[=arg]");
|
||||
assert(p < max_opt_len); // there would be magic if p >= max_opt_len
|
||||
printf("%-*s%s\n", max_opt_len+1, buf, PRNT(opts->help)); // write options & at least 2 spaces after
|
||||
}while((++opts)->name);
|
||||
printf("\n\n");
|
||||
exit(-1);
|
||||
}
|
||||
423
src/saveimg.c
Normal file
423
src/saveimg.c
Normal file
@ -0,0 +1,423 @@
|
||||
/*
|
||||
* saveimg.c - functions to save data in png and FITS formats
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "mkHartmann.h"
|
||||
#include "cmdlnopts.h" // for flag "-f", which will tell to rewrite existing file
|
||||
#include "saveimg.h"
|
||||
#if defined __PNG && __PNG == TRUE
|
||||
#include <png.h>
|
||||
#endif // PNG
|
||||
#if defined __JPEG && __JPEG == TRUE
|
||||
#include <jpeglib.h>
|
||||
#endif // JPEG
|
||||
#if defined __TIFF && __TIFF == TRUE
|
||||
#include <tiffio.h>
|
||||
#endif // TIFF
|
||||
#include <fitsio.h>
|
||||
|
||||
//char *strdup(const char *s);
|
||||
|
||||
#define TRYFITS(f, ...) \
|
||||
do{int status = 0; f(__VA_ARGS__, &status); \
|
||||
if (status){ ret = 0; \
|
||||
fits_report_error(stderr, status); \
|
||||
goto returning;} \
|
||||
}while(0)
|
||||
#define WRITEKEY(...) \
|
||||
do{ int status = 0; \
|
||||
fits_write_key(fp, __VA_ARGS__, &status);\
|
||||
if(status) \
|
||||
fits_report_error(stderr, status); \
|
||||
}while(0)
|
||||
|
||||
int rewrite_ifexists = 0; // don't rewrite existing files
|
||||
/**
|
||||
* Create filename as outfile + number + "." + suffix
|
||||
* number -- any number from 1 to 9999
|
||||
* This function simply returns "outfile.suffix" when "-f" option is set
|
||||
*
|
||||
* @param outfile - file name
|
||||
* @param suffix - file suffix
|
||||
* @return created filename or NULL
|
||||
*/
|
||||
char *createfilename(char* outfile, char* suffix){
|
||||
FNAME();
|
||||
struct stat filestat;
|
||||
char buff[256], sfx[32];
|
||||
if(suffix) snprintf(sfx, 31, ".%s", suffix);
|
||||
else sfx[0] = 0; // no suffix
|
||||
if(rewrite_ifexists){ // there was key "-f": simply return copy of filename
|
||||
if(snprintf(buff, 255, "%s%s", outfile, sfx) < 1){
|
||||
DBG("error");
|
||||
return NULL;
|
||||
}
|
||||
DBG("(-f present) filename: %s", buff);
|
||||
return strdup(buff);
|
||||
}
|
||||
int num;
|
||||
if(!outfile) outfile = "";
|
||||
for(num = 1; num < 10000; num++){
|
||||
if(snprintf(buff, 255, "%s_%04d%s", outfile, num, sfx) < 1){
|
||||
DBG("error");
|
||||
return NULL;
|
||||
}
|
||||
if(stat(buff, &filestat)){ // || !S_ISREG(filestat.st_mode)) // OK, file not exists
|
||||
DBG("filename: %s", buff);
|
||||
return strdup(buff);
|
||||
}
|
||||
}
|
||||
DBG("n: %s\n", buff);
|
||||
WARN("Oops! All numbers are busy or other error!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
float *image;
|
||||
double min;
|
||||
double max;
|
||||
double avr;
|
||||
double std;
|
||||
} ImStat;
|
||||
|
||||
static ImStat glob_stat;
|
||||
|
||||
/**
|
||||
* compute basics image statictics
|
||||
* @param img - image data
|
||||
* @param size - image size W*H
|
||||
* @return
|
||||
*/
|
||||
void get_stat(float *img, size_t size){
|
||||
FNAME();
|
||||
if(glob_stat.image == img) return;
|
||||
size_t i;
|
||||
double pv, sum=0., sum2=0., sz=(double)size;
|
||||
double max = -1., min = 1e15;
|
||||
for(i = 0; i < size; i++){
|
||||
pv = (double) *img++;
|
||||
sum += pv;
|
||||
sum2 += (pv * pv);
|
||||
if(max < pv) max = pv;
|
||||
if(min > pv) min = pv;
|
||||
}
|
||||
glob_stat.avr = sum/sz;
|
||||
glob_stat.std = sqrt(fabs(sum2/sz - glob_stat.avr*glob_stat.avr));
|
||||
glob_stat.max = max;
|
||||
glob_stat.min = min;
|
||||
DBG("Image stat: max=%g, min=%g, avr=%g, std=%g", max, min, glob_stat.avr, glob_stat.std);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data to fits file
|
||||
* @param filename - filename to save to
|
||||
* @param width, height - image size
|
||||
* @param imbox - image bounding box
|
||||
* @data image data
|
||||
* @return 0 if failed
|
||||
*/
|
||||
int writefits(char *filename, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data){
|
||||
FNAME();
|
||||
long naxes[2] = {width, height};
|
||||
char buf[80];
|
||||
int ret = 1;
|
||||
double dX, dY;
|
||||
if(imbox){
|
||||
dX = imbox->w / (double)(width - 1);
|
||||
dY = imbox->h / (double)(height - 1);
|
||||
}
|
||||
time_t savetime = time(NULL);
|
||||
fitsfile *fp;
|
||||
get_stat(data, width*height);
|
||||
assert(filename);
|
||||
char* newname = MALLOC(char, strlen(filename + 2));
|
||||
sprintf(newname, "!%s", filename); // say cfitsio that file could be rewritten
|
||||
TRYFITS(fits_create_file, &fp, newname);
|
||||
TRYFITS(fits_create_img, fp, FLOAT_IMG, 2, naxes);
|
||||
// FILE / Input file original name
|
||||
WRITEKEY(TSTRING, "FILE", filename, "Input file original name");
|
||||
free(newname);
|
||||
WRITEKEY(TSTRING, "DETECTOR", "Hartmann model", "Detector model");
|
||||
if(imbox){
|
||||
snprintf(buf, 79, "%.2g x %.2g", dX * 1e6, dY * 1e6);
|
||||
// PXSIZE / pixel size
|
||||
WRITEKEY(TSTRING, "PXSIZE", buf, "Pixel size in mkm");
|
||||
// XPIXELSZ, YPIXELSZ -- the same
|
||||
WRITEKEY(TDOUBLE, "XPIXELSZ", &dX, "X pixel size in m");
|
||||
WRITEKEY(TDOUBLE, "YPIXELSZ", &dY, "Y pixel size in m");
|
||||
// LBCX, LBCY / Coordinates of left bottom corner
|
||||
WRITEKEY(TFLOAT, "LBCX", &imbox->x0, "X of left bottom corner");
|
||||
WRITEKEY(TFLOAT, "LBCY", &imbox->y0, "Y of left bottom corner");
|
||||
}
|
||||
// IMAGETYP / object, flat, dark, bias, scan, eta, neon, push
|
||||
WRITEKEY(TSTRING, "IMAGETYP", "object", "Image type");
|
||||
// DATAMAX, DATAMIN / Max,min pixel value
|
||||
WRITEKEY(TDOUBLE, "DATAMAX", &glob_stat.max, "Max data value");
|
||||
WRITEKEY(TDOUBLE, "DATAMIN", &glob_stat.min, "Min data value");
|
||||
// Some Statistics
|
||||
WRITEKEY(TDOUBLE, "DATAAVR", &glob_stat.avr, "Average data value");
|
||||
WRITEKEY(TDOUBLE, "DATASTD", &glob_stat.std, "Standart deviation of data value");
|
||||
// DATE / Creation date (YYYY-MM-DDThh:mm:ss, UTC)
|
||||
strftime(buf, 79, "%Y-%m-%dT%H:%M:%S", gmtime(&savetime));
|
||||
WRITEKEY(TSTRING, "DATE", buf, "Creation date (YYYY-MM-DDThh:mm:ss, UTC)");
|
||||
// DATE-OBS / DATE OF OBS.
|
||||
WRITEKEY(TSTRING, "DATE-OBS", buf, "DATE OF OBS. (YYYY-MM-DDThh:mm:ss, local)");
|
||||
// OBJECT / Object name
|
||||
WRITEKEY(TSTRING, "OBJECT", "Modeled object", "Object name");
|
||||
// BINNING / Binning
|
||||
WRITEKEY(TSTRING, "XBIN", "1", "Horizontal binning");
|
||||
WRITEKEY(TSTRING, "YBIN", "1", "Vertical binning");
|
||||
// PROG-ID / Observation program identifier
|
||||
WRITEKEY(TSTRING, "PROG-ID", "BTA Hartmann modeling", "Observation program identifier");
|
||||
// AUTHOR / Author of the program
|
||||
WRITEKEY(TSTRING, "AUTHOR", "Edward V. Emelianov", "Author of the program");
|
||||
if(mirror){
|
||||
WRITEKEY(TFLOAT, "MIRDIAM", &mirror->D, "Mirror diameter");
|
||||
WRITEKEY(TFLOAT, "MIRFOC", &mirror->F, "Mirror focus ratio");
|
||||
WRITEKEY(TFLOAT, "MIRZINCL", &mirror->Zincl,"Mirror inclination from Z axe");
|
||||
WRITEKEY(TFLOAT, "MIRAINCL", &mirror->Aincl,"Azimuth of mirror inclination");
|
||||
WRITEKEY(TFLOAT, "A", &mirror->objA, "Object's azimuth");
|
||||
WRITEKEY(TFLOAT, "Z", &mirror->objZ, "Object's zenith distance");
|
||||
WRITEKEY(TFLOAT, "FOCUS", &mirror->foc, "Z-coordinate of light receiver");
|
||||
}
|
||||
TRYFITS(fits_write_img, fp, TFLOAT, 1, width * height, data);
|
||||
TRYFITS(fits_close_file, fp);
|
||||
|
||||
returning:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t *rowptr = NULL;
|
||||
uint8_t *processRow(float *irow, size_t width, float min, float wd){
|
||||
FREE(rowptr);
|
||||
//float umax = ((float)(UINT16_MAX-1));
|
||||
rowptr = MALLOC(uint8_t, width * 3);
|
||||
OMP_FOR()
|
||||
for(size_t i = 0; i < width; i++){
|
||||
//*ptr = (uint16_t)(umax*(*irow - min)/wd);
|
||||
double gray = ((double)(irow[i] - min))/((double)wd);
|
||||
if(gray == 0.) continue;
|
||||
int G = (int)(gray * 4.);
|
||||
double x = 4.*gray - (double)G;
|
||||
uint8_t r = 0, g = 0, b = 0;
|
||||
uint8_t *ptr = &rowptr[i*3];
|
||||
switch(G){
|
||||
case 0:
|
||||
g = (uint8_t)(255. * x + 0.5);
|
||||
b = 255;
|
||||
break;
|
||||
case 1:
|
||||
g = 255;
|
||||
b = (uint8_t)(255. * (1. - x) + 0.5);
|
||||
break;
|
||||
case 2:
|
||||
r = (uint8_t)(255. * x + 0.5);
|
||||
g = 255;
|
||||
break;
|
||||
case 3:
|
||||
r = 255;
|
||||
g = (uint8_t)(255. * (1. - x) + 0.5);
|
||||
break;
|
||||
default:
|
||||
r = 255;
|
||||
}
|
||||
ptr[0] = r; ptr[1] = g; ptr[2] = b;
|
||||
//ptr[0] = ptr[1] = ptr[2] = gray*255;
|
||||
}
|
||||
return rowptr;
|
||||
}
|
||||
|
||||
int writepng(char *filename, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data){
|
||||
FNAME();
|
||||
int ret = 1;
|
||||
#if defined __PNG && __PNG == TRUE
|
||||
FILE *fp = NULL;
|
||||
png_structp pngptr = NULL;
|
||||
png_infop infoptr = NULL;
|
||||
get_stat(data, width*height);
|
||||
float min = glob_stat.min, wd = glob_stat.max - min;
|
||||
float *row;
|
||||
|
||||
if ((fp = fopen(filename, "w")) == NULL){
|
||||
perror("Can't open png file");
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
if ((pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL)) == NULL){
|
||||
perror("Can't create png structure");
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
if ((infoptr = png_create_info_struct(pngptr)) == NULL){
|
||||
perror("Can't create png info structure");
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
png_init_io(pngptr, fp);
|
||||
png_set_compression_level(pngptr, 1);
|
||||
png_set_IHDR(pngptr, infoptr, width, height, 8, PNG_COLOR_TYPE_RGB,//16, PNG_COLOR_TYPE_GRAY,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
png_write_info(pngptr, infoptr);
|
||||
png_set_swap(pngptr);
|
||||
for(row = &data[width*(height-1)]; height > 0; row -= width, height--)
|
||||
png_write_row(pngptr, (png_bytep)processRow(row, width, min, wd));
|
||||
png_write_end(pngptr, infoptr);
|
||||
done:
|
||||
if(fp) fclose(fp);
|
||||
if(pngptr) png_destroy_write_struct(&pngptr, &infoptr);
|
||||
#else
|
||||
WARN("Save to PNG doesn't supported");
|
||||
#endif // PNG
|
||||
return ret;
|
||||
}
|
||||
|
||||
int writejpg(char *filename, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data){
|
||||
FNAME();
|
||||
int ret = 1;
|
||||
#if defined __JPEG && __JPEG == TRUE
|
||||
get_stat(data, width*height);
|
||||
float min = glob_stat.min, wd = glob_stat.max - min;
|
||||
float *row;
|
||||
FILE* outfile = fopen(filename, "w");
|
||||
if(!outfile){
|
||||
perror("Can't open jpg file");
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_stdio_dest(&cinfo, outfile);
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = 3;
|
||||
cinfo.in_color_space = JCS_RGB;
|
||||
jpeg_set_defaults(&cinfo);
|
||||
jpeg_set_quality (&cinfo, 99, 1);
|
||||
jpeg_start_compress(&cinfo, 1);
|
||||
JSAMPROW row_pointer;
|
||||
for(row = &data[width*(height-1)]; height > 0; row -= width, height--){
|
||||
row_pointer = (JSAMPROW)processRow(row, width, min, wd);
|
||||
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
||||
}
|
||||
jpeg_finish_compress(&cinfo);
|
||||
done:
|
||||
if(outfile) fclose(outfile);
|
||||
#else
|
||||
WARN("Save to JPEG doesn't supported");
|
||||
#endif // JPEG
|
||||
return ret;
|
||||
}
|
||||
|
||||
int writetiff(char *filename, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data){
|
||||
FNAME();
|
||||
int ret = 1;
|
||||
#if defined __TIFF && __TIFF == TRUE
|
||||
get_stat(data, width*height);
|
||||
float min = glob_stat.min, wd = glob_stat.max - min;
|
||||
float *row;
|
||||
TIFF *image = TIFFOpen(filename, "w");
|
||||
if(!image){
|
||||
perror("Can't open tiff file");
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width);
|
||||
TIFFSetField(image, TIFFTAG_IMAGELENGTH, height);
|
||||
TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, 3);
|
||||
TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1);
|
||||
TIFFSetField(image, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
|
||||
TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
|
||||
TIFFSetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||
TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
|
||||
tstrip_t strip = 0;
|
||||
for(row = data; strip < height; row += width, strip++){
|
||||
TIFFWriteEncodedStrip(image, strip, processRow(row, width, min, wd), width * 3);
|
||||
//TIFFWriteScanline
|
||||
}
|
||||
done:
|
||||
if(image) TIFFClose(image);
|
||||
#else
|
||||
WARN("Save to TIFF doesn't supported");
|
||||
#endif // TIFF
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
typedef struct{
|
||||
imtype t;
|
||||
char *s;
|
||||
int (*writefn)(char *, size_t, size_t, BBox *, mirPar *, float *);
|
||||
}itsuff;
|
||||
|
||||
static itsuff suffixes[] = {
|
||||
{IT_FITS, "fits", writefits},
|
||||
{IT_PNG, "png", writepng},
|
||||
{IT_JPEG, "jpeg", writejpg},
|
||||
{IT_TIFF, "tiff", writetiff},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
/**
|
||||
* Save data to image file[s] with format t
|
||||
* @param name - filename prefix or NULL to save to "outXXXX.format"
|
||||
* @param t - image[s] type[s]
|
||||
* @param width, height - image size
|
||||
* @param imbox - image bounding box (for FITS header)
|
||||
* @param mirror - mirror parameters (for FITS header)
|
||||
* @param data image data
|
||||
* @return number of saved images
|
||||
*/
|
||||
int writeimg(char *name, imtype t, size_t width, size_t height, BBox *imbox,
|
||||
mirPar *mirror, float *data){
|
||||
FNAME();
|
||||
char *filename = NULL, *suffix;
|
||||
int ret = 0;
|
||||
itsuff *suf = suffixes;
|
||||
while(t && suf->t){
|
||||
if(!(t & suf->t)){
|
||||
suf++;
|
||||
continue;
|
||||
}
|
||||
t ^= suf->t;
|
||||
suffix = suf->s;
|
||||
FREE(filename);
|
||||
if(name)
|
||||
filename = createfilename(name, suffix);
|
||||
else
|
||||
filename = createfilename("out", suffix);
|
||||
if(!filename){
|
||||
fprintf(stderr, "Create file with name %s and suffix %s failed,\n", name, suffix);
|
||||
perror("can't make filename");
|
||||
continue;
|
||||
}
|
||||
if(suf->writefn(filename, width, height, imbox, mirror, data)) ret++;
|
||||
}
|
||||
FREE(filename);
|
||||
return ret;
|
||||
}
|
||||
25
src/test/capability.cu
Normal file
25
src/test/capability.cu
Normal file
@ -0,0 +1,25 @@
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv){
|
||||
cudaDeviceProp dP;
|
||||
//CUdevice dev;
|
||||
//CUcontext ctx;
|
||||
if(cudaSuccess != cudaGetDeviceProperties(&dP, 0)) return 0;
|
||||
/*if(CUDA_SUCCESS != cuDeviceGet(&dev,0)) return 0;
|
||||
|
||||
// create context for program run:
|
||||
if(CUDA_SUCCESS != cuCtxCreate(&ctx, 0, dev)) return 0;
|
||||
printf("\nDevice: %s, totalMem=%zd, memPerBlk=%zd,\n", dP.name, dP.totalGlobalMem, dP.sharedMemPerBlock);
|
||||
printf("warpSZ=%d, TPB=%d, TBDim=%dx%dx%d\n", dP.warpSize, dP.maxThreadsPerBlock,
|
||||
dP.maxThreadsDim[0],dP.maxThreadsDim[1],dP.maxThreadsDim[2]);
|
||||
printf("GridSz=%dx%dx%d, MemovrLap=%d, GPUs=%d\n", dP.maxGridSize[0],
|
||||
dP.maxGridSize[1],dP.maxGridSize[2],
|
||||
dP.deviceOverlap, dP.multiProcessorCount);
|
||||
printf("canMAPhostMEM=%d\n", dP.canMapHostMemory);
|
||||
printf("compute capability");*/
|
||||
printf("-arch=sm_%d%d\n", dP.major, dP.minor);
|
||||
//cuCtxDetach(ctx);
|
||||
return 0;
|
||||
}
|
||||
373
src/wrapper.c
Normal file
373
src/wrapper.c
Normal file
@ -0,0 +1,373 @@
|
||||
/*
|
||||
* wrapper.c - CPU / GPU wrapper, try to run function on GPU, if fail - on CPU
|
||||
*
|
||||
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define WRAPPER_C
|
||||
#include "wrapper.h"
|
||||
#ifdef EBUG
|
||||
#include "saveimg.h"
|
||||
#endif
|
||||
|
||||
// Functions to manipulate of forced CPU execution ============================>
|
||||
void noCUDA(){ // force run on CPU
|
||||
Only_CPU = 1;
|
||||
CUforce = 0;
|
||||
}
|
||||
void tryCUDA(){ // return to default state
|
||||
#ifdef CUDA_FOUND
|
||||
Only_CPU = 0;
|
||||
CUforce = 0;
|
||||
#else
|
||||
/// "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
WARN(_("Tool was compiled without CUDA support"));
|
||||
#endif
|
||||
}
|
||||
int CUsuccess(){ // test if CU faield
|
||||
#ifdef CUDA_FOUND
|
||||
if(Only_CPU) return 0;
|
||||
else return CUnoerr;
|
||||
#else
|
||||
/// "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
WARN(_("Tool was compiled without CUDA support"));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
void forceCUDA(){ // not run on CPU even if GPU failed
|
||||
#ifdef CUDA_FOUND
|
||||
Only_CPU = 0;
|
||||
CUforce = 1;
|
||||
#else
|
||||
/// "ðÒÉÌÏÖÅÎÉÅ ÓËÏÍÐÉÌÉÒÏ×ÁÎÏ ÂÅÚ ÐÏÄÄÅÒÖËÉ CUDA"
|
||||
WARN(_("Tool was compiled without CUDA support"));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Init function ==============================================================>
|
||||
/*
|
||||
* Init CUDA context and/or test memory allocation
|
||||
* name: getprops
|
||||
*/
|
||||
void getprops(){
|
||||
FNAME();
|
||||
size_t mem = 100 * MB;
|
||||
/// "ôÅÓÔ ÎÁ ×ÙÄÅÌÅÎÉÅ ËÁË ÍÉÎÉÍÕÍ 100íâ ÐÁÍÑÔÉ\n"
|
||||
printf("Make a test for allocation at least 100MB memory\n");
|
||||
#ifdef CUDA_FOUND
|
||||
/// "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÐÏ ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ GPU\n"
|
||||
red(_("In computations will try to use GPU\n"));
|
||||
int status = 0;
|
||||
char *errors[] = {
|
||||
"",
|
||||
/// "ïÛÉÂËÁ ÐÏÌÕÞÅÎÉÑ Ó×ÏÊÓÔ× ×ÉÄÅÏÑÄÒÁ"
|
||||
_("Can't get properties"),
|
||||
/// "ïÛÉÂËÁ ÏÐÒÅÄÅÌÅÎÉÑ ÄÏÓÔÕÐÎÏÊ ÐÁÍÑÔÉ"
|
||||
_("Can't determine free memory"),
|
||||
/// "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
_("Can't allocate memory")
|
||||
};
|
||||
size_t theFree, theTotal;
|
||||
do{
|
||||
#define _TEST(F, st) if(!F){status = st;break;}
|
||||
_TEST(CUgetprops(), 1);
|
||||
_TEST(CUgetMEM(0, &theFree, &theTotal), 2);
|
||||
// if there is enough memory
|
||||
if(theFree / 4 > mem) mem = theFree / 4;
|
||||
// try to allocate GPU memory
|
||||
_TEST(CUallocaTest(mem), 3);
|
||||
#undef _TEST
|
||||
}while(0);
|
||||
if(status){
|
||||
Only_CPU = 1;
|
||||
/// "ïÛÉÂËÁ × ÉÎÉÃÉÁÌÉÚÁÃÉÉ CUDA!"
|
||||
WARN(_("Error in CUDA initialisation!"));
|
||||
WARN(errors[status]);
|
||||
}else{
|
||||
/// "ðáíñôø: Ó×ÏÂÏÄÎÁÑ = "
|
||||
printf(_("MEMORY: free = "));
|
||||
green("%zdMB,", theFree / MB);
|
||||
/// " ÓÕÍÍÁÒÎÁÑ = "
|
||||
printf(_(" total= "));
|
||||
green("%zdMB\n", theTotal / MB);
|
||||
}
|
||||
#endif
|
||||
if(Only_CPU){
|
||||
/// "÷ ×ÙÞÉÓÌÅÎÉÑÈ ÉÓÐÏÌØÚÕÅÔÓÑ ÔÏÌØËÏ CPU\n"
|
||||
green(_("Will use only CPU in computations\n"));
|
||||
}
|
||||
// at last step - try to allocate main memory
|
||||
char *ptr = (char *) malloc(mem);
|
||||
/// "ïÛÉÂËÁ ×ÙÄÅÌÅÎÉÑ ÐÁÍÑÔÉ"
|
||||
if(!ptr || !memset(ptr, 0xaa, mem)) ERR("Error allocating memory");
|
||||
free(ptr);
|
||||
/// "ôÅÓÔ ×ÙÄÅÌÅÎÉÑ 100íâ ÐÁÍÑÔÉ ÐÒÏÊÄÅÎ ÕÓÐÅÛÎÏ\n"
|
||||
printf(_("Allocation test for 100MB of memory passed\n"));
|
||||
if(!status){
|
||||
/// "\n\n÷ÓÅ ÔÅÓÔÙ ÐÒÏÊÄÅÎÙ ÕÓÐÅÛÎÏ"
|
||||
green(_("\n\nAll tests succeed"));
|
||||
printf("\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Functions for pseudo-random number generators initialisation ===============>
|
||||
/*
|
||||
* Current time in seconds since UNIX epoch
|
||||
* name: dtime
|
||||
* @return time in seconds
|
||||
*/
|
||||
double dtime(){
|
||||
double t;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
t = tv.tv_sec + ((double)tv.tv_usec)/1e6;
|
||||
return t;
|
||||
}
|
||||
/*
|
||||
* Generate a quasy-random number to initialize PRNG
|
||||
* name: throw_random_seed
|
||||
* @return value for curandSetPseudoRandomGeneratorSeed or srand48
|
||||
*/
|
||||
long throw_random_seed(){
|
||||
//FNAME();
|
||||
long r_ini;
|
||||
int fail = 0;
|
||||
int fd = open("/dev/random", O_RDONLY);
|
||||
do{
|
||||
if(-1 == fd){
|
||||
/// "îÅ ÍÏÇÕ ÏÔËÒÙÔØ"
|
||||
WARN("%s /dev/random!", _("Can't open"));
|
||||
fail = 1; break;
|
||||
}
|
||||
if(sizeof(long) != read(fd, &r_ini, sizeof(long))){
|
||||
/// "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ"
|
||||
WARN("%s /dev/random!", _("Can't read"));
|
||||
fail = 1;
|
||||
}
|
||||
close(fd);
|
||||
}while(0);
|
||||
if(fail){
|
||||
double tt = dtime() * 1e6;
|
||||
double mx = (double)LONG_MAX;
|
||||
r_ini = (long)(tt - mx * floor(tt/mx));
|
||||
}
|
||||
return (r_ini);
|
||||
}
|
||||
|
||||
// Build mask ===================================================>
|
||||
/**
|
||||
* Make an array which elements identify corresponding hole's box for given
|
||||
* box (pixel) on mirror
|
||||
* It try to make mask size of minSz, but if light from some "pixels" will fall
|
||||
* onto more than one hole, size would be increased 2 times. Iterations of
|
||||
* increasing mask size would continue till photons from every "pixel" would
|
||||
* fall only on one hole
|
||||
*
|
||||
* Builded mask attached to input diaphragm as d->mask, before attach a freeDmask()
|
||||
* is called, so BE CAREFULL! First run of makeDmask() should be with d->mask == NULL!
|
||||
*
|
||||
* Mask is an image with cartesian coordinates -> it looks like horizontally mirroring!
|
||||
*
|
||||
* @param d - diaphragm for mask making
|
||||
* @param minSz - minimal mask size
|
||||
* @param M - mirror parameters
|
||||
* @param D - mirror deviations
|
||||
* @return allocated mask (MUST BE FREE by freeDmask) or NULL in case of error
|
||||
*/
|
||||
mirMask *makeDmask(Diaphragm *d, size_t minSz, mirPar *M, mirDeviations *D){
|
||||
FNAME();
|
||||
if(minSz > 4096){
|
||||
WARNX("Size of matrix (%d^2) too large!", minSz);
|
||||
return NULL;
|
||||
}
|
||||
if(minSz < 4) minSz = 4;
|
||||
size_t S2;
|
||||
int x, y, N;
|
||||
uint16_t *mdata = NULL, *ddata = NULL; // arrays for diaphragm & mask
|
||||
mirPar mirror;
|
||||
memcpy(&mirror, M, sizeof(mirPar));
|
||||
mirror.foc = d->Z; // preparing for getPhotonXY
|
||||
DBG("minSz = %zd", minSz);
|
||||
S2 = minSz * minSz;
|
||||
// width & height of "pixel"
|
||||
double scalex = d->box.w/(double)minSz, scaley = d->box.h/(double)minSz;
|
||||
|
||||
ddata = MALLOC(uint16_t, S2);
|
||||
// fill diafragm mask to identify which hole to check when "photon"
|
||||
// falls into that region; fill only BBoxes!
|
||||
for(N = d->Nholes-1; N > -1; N--){
|
||||
BBox *b = &(d->holes[N].box);
|
||||
// coordinates of hole x0, y0 relative to diaphragm x0,y0
|
||||
double X0 = (b->x0 - d->box.x0)/scalex, Y0 = (b->y0 - d->box.y0)/scaley;
|
||||
// coordinates of upper right corner, add 2. to substitute <= to < in next cycles & to avoid border loss
|
||||
int x1 = (int)(X0 + b->w/scalex + 2.), y1 = (int)(Y0 + b->h/scaley + 2.);
|
||||
int x0 = (int)X0, y0 = (int)Y0;
|
||||
//DBG("scalex: %f scaley: %f, x0=%d, y0=%d, x1=%d, y1=%d\n", scalex, scaley, x0,y0,x1,y1);
|
||||
uint16_t mark = N + 1;
|
||||
if(y1 - y0 < 1 || x1 - x0 < 1){ // don't allow scale less than 1pix per hole
|
||||
DBG("Scale: too little");
|
||||
FREE(ddata);
|
||||
return makeDmask(d, minSz*2, M, D);
|
||||
}
|
||||
if(y1 > minSz) y1 = minSz;
|
||||
if(y0 < 0) y0 = 0;
|
||||
if(x1 > minSz) x1 = minSz;
|
||||
if(x0 < 0) x0 = 0;
|
||||
for(y = y0; y < y1; y++){
|
||||
uint16_t *ptr = &ddata[y*minSz + x0];
|
||||
for(x = x0; x < x1; x++, ptr++){
|
||||
if(*ptr && *ptr != mark){ // zone already occupied, make grid smaller
|
||||
DBG("Ooops, occupied zone (marker=%d, found %d); try minSz = %zd",mark, *ptr, minSz*2);
|
||||
FREE(ddata);
|
||||
return makeDmask(d, minSz*2, M, D);
|
||||
}
|
||||
*ptr = mark;
|
||||
}
|
||||
}
|
||||
}
|
||||
// prepare photons
|
||||
// they "falls" to corners of inner grid of size (minSz-1)^2
|
||||
S2 = (minSz-1)*(minSz-1);
|
||||
ALLOC(float, Xp, S2);
|
||||
ALLOC(float, Yp, S2);
|
||||
// prepare coordinates of "photons"
|
||||
double mY = 0., dist = 1./(double)(minSz - 2); // distance between points on grid 0..1
|
||||
float *xptr = Xp, *yptr = Yp;
|
||||
for(y = 1; y < minSz; y++, mY += dist){
|
||||
double mX = 0.;
|
||||
for(x = 1; x < minSz; x++, mX += dist){
|
||||
*yptr++ = mY;
|
||||
*xptr++ = mX;
|
||||
}
|
||||
}
|
||||
double mdxy = mirror.D/(double)minSz; // scale on mirror
|
||||
// box for grid
|
||||
BBox mirB = {-mirror.D/2.+mdxy, -mirror.D/2.+mdxy, mirror.D-2*mdxy, mirror.D-2*mdxy};
|
||||
DBG("mirbox: LD/UR = %g, %g, %g, %g",mirB.x0, mirB.y0, mirB.w+mirB.x0, mirB.h+mirB.y0);
|
||||
if(!getPhotonXY(Xp, Yp, 0, D, &mirror, S2, &mirB)){
|
||||
FREE(Xp); FREE(Yp); FREE(ddata);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef EBUG
|
||||
float minx=1000.,miny=1000.,maxx=-1000., maxy=-1000.;
|
||||
for(x=0;x<S2;x++){if(minx > Xp[x])minx=Xp[x]; else if(maxx < Xp[x] && Xp[x] < 1e8) maxx = Xp[x];
|
||||
if(miny > Yp[x])miny=Yp[x]; else if(maxy < Yp[x] && Yp[x] < 1e8) maxy = Yp[x];}
|
||||
DBG("minx: %g, maxx: %g, miny: %g, maxy: %g", minx,maxx,miny,maxy);
|
||||
#endif
|
||||
float xleft = d->box.x0, ybot = d->box.y0;
|
||||
// and now fill mirror mask
|
||||
int S = minSz - 1;
|
||||
mdata = MALLOC(uint16_t, minSz*minSz);
|
||||
ALLOC(uint8_t, histo, d->Nholes);
|
||||
DBG("xleft: %g, scalex: %g", xleft, scalex);
|
||||
xptr = Xp; yptr = Yp;
|
||||
for(y = 0; y < S; y++){
|
||||
for(x = 0; x < S; x++, xptr++, yptr++){
|
||||
if(*xptr > 1e9 || *yptr > 1e9) continue; // miss to mirror
|
||||
int curX = (int)((*xptr - xleft) / scalex);
|
||||
if(curX < 0 || curX >= S) continue; // miss
|
||||
int curY = (int)((*yptr - ybot) / scaley);
|
||||
if(curY < 0 ||curY >= S) continue; // miss
|
||||
uint16_t mark = ddata[curY*minSz + curX];
|
||||
if(!mark) continue; // no hole
|
||||
int pix = y*minSz + x;
|
||||
int err = 0;
|
||||
histo[mark-1] = 1; // mark hole as proceeded
|
||||
#define CHECK(X) if(mdata[X]&&mdata[X]!=mark){err=1;}else{mdata[X]=mark;}
|
||||
CHECK(pix); // pixel to the left and down
|
||||
CHECK(pix+1); // right and down
|
||||
CHECK(pix+minSz); // left & up
|
||||
CHECK(pix+minSz+1); // right & up
|
||||
#undef CHECK
|
||||
if(err){ // zone already occupied, make grid smaller
|
||||
DBG("Ooops, occupied zone; try minSz = %zd", minSz*2);
|
||||
FREE(Xp); FREE(Yp); FREE(ddata); FREE(mdata); FREE(histo);
|
||||
return makeDmask(d, minSz*2, M, D);
|
||||
}
|
||||
}
|
||||
}
|
||||
FREE(Xp); FREE(Yp); FREE(ddata);
|
||||
// Now chek whether all holes are present
|
||||
for(x = 0; x < d->Nholes; x++)
|
||||
if(!histo[x]){
|
||||
DBG("Oooops! Missed a hole!");
|
||||
FREE(mdata);
|
||||
return makeDmask(d, minSz*2, M, D);
|
||||
}
|
||||
#ifdef EBUG
|
||||
int totalpts = 0; S2 = minSz*minSz; uint16_t *ptr = mdata;
|
||||
for(x=0;x<S2;x++,ptr++)if(*ptr)totalpts++;
|
||||
red("Total non-zero points on mask: %d (%.1f%%)", totalpts,100.*(double)totalpts/(double)S2);
|
||||
printf("\n");
|
||||
#endif
|
||||
FREE(histo);
|
||||
ALLOC(mirMask, Mask, 1);
|
||||
Mask->WH = minSz;
|
||||
Mask->data = mdata;
|
||||
freeDmask(d->mask);
|
||||
d->mask = Mask;
|
||||
return Mask;
|
||||
}
|
||||
|
||||
void freeDmask(mirMask *m){
|
||||
if(!m) return;
|
||||
FREE(m->data);
|
||||
FREE(m);
|
||||
}
|
||||
|
||||
// Build image ================================================================>
|
||||
|
||||
/**
|
||||
* fill matrix image with photons
|
||||
* @param phX, phY - photons coordinates
|
||||
* @param ph_sz - number of photons
|
||||
* @param image - resulting image (photons **adds** to it)
|
||||
* @param imW, imH - size of resulting image
|
||||
* @param imbox - bounding box of resulting image
|
||||
* @return 0 if fails
|
||||
*/
|
||||
int fillImage(float *phX, float *phY, size_t ph_sz,
|
||||
float *image, size_t imW, size_t imH, BBox *imbox){
|
||||
FNAME();
|
||||
float x0 = imbox->x0, y0 = imbox->y0, x1 = imbox->x0 + imbox->w, y1 = imbox->y0 + imbox->h;
|
||||
float dX = imbox->w / (float)(imW - 1), dY = imbox->h / (float)(imH - 1), x=0,y=0;
|
||||
size_t N;
|
||||
#ifdef EBUG
|
||||
float sum = 0., miss = 0., Xc = 0., Yc = 0.;
|
||||
#endif
|
||||
for(N = 0; N < ph_sz; N++){
|
||||
x = phX[N]; y = phY[N];
|
||||
size_t X,Y;
|
||||
if(x < x0 || x > x1 || y < y0 || y > y1){
|
||||
#ifdef EBUG
|
||||
miss += 1.;
|
||||
#endif
|
||||
}else{
|
||||
X = (size_t)((x - x0) / dX + 0.5);
|
||||
Y = (size_t)((y1 - y) / dY + 0.5);
|
||||
image[Y*imW + X] += 1.f;
|
||||
#ifdef EBUG
|
||||
sum += 1.;
|
||||
Xc += x; Yc += y;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
DBG("Photons on image: %g, missed: %g; TOTAL: %g\ncenter: Xc=%gmm, Yc=%gmm\nPI=%g",
|
||||
sum,miss, sum+miss, Xc/sum*1000., Yc/sum*1000., 4.*sum/(sum+miss));
|
||||
return 1;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user