SourceXtractorPlusPlus
0.21
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
SEFramework
src
lib
Psf
VariablePsfStack.cpp
Go to the documentation of this file.
1
17
/*
18
* VariablePsfStack.cpp
19
*
20
* Created on: July 10, 2019
21
* Author: Martin Kuemmel
22
*/
23
#include <algorithm>
24
#include <ElementsKernel/Logging.h>
25
#include <ElementsKernel/Exception.h>
26
#include "
SEFramework/Psf/VariablePsfStack.h
"
27
28
static
auto
stack_logger
=
Elements::Logging::getLogger
(
"VarStackPsf"
);
29
30
namespace
SourceXtractor
{
31
32
void
VariablePsfStack::setup
(
std::shared_ptr<CCfits::FITS>
pFits
) {
33
try
{
34
// basic check: load the primary HDU
35
CCfits::PHDU&
phdu
=
pFits
->pHDU();
36
if
(
phdu
.axes() != 0) {
37
throw
Elements::Exception
() <<
"The primary HDU is not empty! File: "
<<
pFits
->name();
38
}
39
40
// basic check: load the first extension
41
CCfits::ExtHDU&
psf_data
=
pFits
->extension(1);
42
if
(
psf_data
.axes() != 2) {
43
throw
Elements::Exception
() <<
"The first HDU is not an image! File: "
<<
pFits
->name();
44
}
45
46
// basic check: load the second extension
47
CCfits::ExtHDU&
position_data
=
pFits
->extension(2);
48
if
(
position_data
.axes() != 2) {
49
throw
Elements::Exception
() <<
"The second HDU has not the right dimension! File: "
<<
pFits
->name();
50
}
51
52
// give some feedback
53
stack_logger
.debug() <<
"Checked the file: "
<<
pFits
->name();
54
55
// get and store the stamp size;
56
// define the offset from GRIDX and GRIDY
57
psf_data
.readKey(
"STMPSIZE"
,
m_psf_size
);
58
m_grid_offset
=
m_psf_size
/ 2;
// this is for CCfits where indices start with 1!
59
60
// make sure the PSF size is odd
61
if
(
m_psf_size
% 2 == 0) {
62
throw
Elements::Exception
() <<
"PSF kernel must have odd size, but has: "
<<
m_psf_size
;
63
}
64
65
try
{
66
// try to get the sampling
67
psf_data
.readKey(
"SAMPLING"
,
mm_pixel_sampling
);
68
}
catch
(CCfits::HDU::NoSuchKeyword&) {
69
// use a default value
70
mm_pixel_sampling
= 1.;
71
}
72
73
// read the nrows value
74
m_nrows
=
position_data
.rows();
75
76
try
{
77
// read in all the EXT specific columns
78
position_data
.column(
"GRIDX"
,
false
).read(
m_gridx_values
, 0,
m_nrows
);
79
position_data
.column(
"GRIDY"
,
false
).read(
m_gridy_values
, 0,
m_nrows
);
80
}
catch
(CCfits::Table::NoSuchColumn) {
81
position_data
.column(
"X_CENTER"
,
false
).read(
m_gridx_values
, 0,
m_nrows
);
82
position_data
.column(
"Y_CENTER"
,
false
).read(
m_gridy_values
, 0,
m_nrows
);
83
}
84
position_data
.column(
"RA"
,
false
).read(
m_ra_values
, 0,
m_nrows
);
85
position_data
.column(
"DEC"
,
false
).read(
m_dec_values
, 0,
m_nrows
);
86
position_data
.column(
"X"
,
false
).read(
m_x_values
, 0,
m_nrows
);
87
position_data
.column(
"Y"
,
false
).read(
m_y_values
, 0,
m_nrows
);
88
89
}
catch
(CCfits::FitsException& e) {
90
throw
Elements::Exception
() <<
"Error loading stacked PSF file: "
<< e.message();
91
}
92
}
93
94
void
VariablePsfStack::selfTest
() {
95
int
naxis1
,
naxis2
;
96
97
// read in the min/max grid values in x/y
98
const
auto
x_grid_minmax
=
std::minmax_element
(
begin
(
m_gridx_values
),
end
(
m_gridx_values
));
99
const
auto
y_grid_minmax
=
std::minmax_element
(
begin
(
m_gridy_values
),
end
(
m_gridy_values
));
100
101
// read the image size
102
m_pFits
->extension(1).readKey(
"NAXIS1"
,
naxis1
);
103
m_pFits
->extension(1).readKey(
"NAXIS2"
,
naxis2
);
104
105
// make sure all PSF in the grid are there
106
if
(*
x_grid_minmax
.first -
m_grid_offset
< 1)
107
throw
Elements::Exception
() <<
"The PSF at the smallest x-grid starts at: "
<< *
x_grid_minmax
.first -
m_grid_offset
;
108
if
(*
y_grid_minmax
.first -
m_grid_offset
< 1)
109
throw
Elements::Exception
() <<
"The PSF at the smallest y-grid starts at: "
<< *
y_grid_minmax
.first -
m_grid_offset
;
110
if
(*
x_grid_minmax
.second +
m_grid_offset
>
naxis1
)
111
throw
Elements::Exception
() <<
"The PSF at the largest x-grid is too large: "
<< *
x_grid_minmax
.second +
m_grid_offset
112
<<
" NAXIS1: "
<<
naxis1
;
113
if
(*
y_grid_minmax
.second +
m_grid_offset
>
naxis2
)
114
throw
Elements::Exception
() <<
"The PSF at the largest y-grid is too large: "
<< *
y_grid_minmax
.second +
m_grid_offset
115
<<
" NAXIS2: "
<<
naxis1
;
116
}
117
118
std::shared_ptr<VectorImage<SeFloat>
>
VariablePsfStack::getPsf
(
const
std::vector<double>
&
values
)
const
{
119
long
index_min_distance
= 0;
120
double
min_distance
= 1.0e+32;
121
122
// make sure there are only two positions
123
if
(
values
.size() != 2)
124
throw
Elements::Exception
() <<
"There can be only two positional value for the stacked PSF!"
;
125
126
// find the position of minimal distance
127
for
(
int
act_index
= 0;
act_index
<
m_nrows
;
act_index
++) {
128
double
act_distance
= (
values
[0] -
m_x_values
[
act_index
]) * (
values
[0] -
m_x_values
[
act_index
]) +
129
(
values
[1] -
m_y_values
[
act_index
]) * (
values
[1] -
m_y_values
[
act_index
]);
130
if
(
act_distance
<
min_distance
) {
131
index_min_distance
=
act_index
;
132
min_distance
=
act_distance
;
133
}
134
}
135
// give some feedback
136
stack_logger
.debug() <<
"Distance: "
<<
sqrt
(
min_distance
) <<
" ("
<<
values
[0] <<
","
<<
values
[1] <<
")<-->("
137
<<
m_x_values
[
index_min_distance
] <<
","
<<
m_y_values
[
index_min_distance
]
138
<<
") index: "
<<
index_min_distance
;
139
140
// get the first and last pixels for the PSF to be extracted
141
// NOTE: CCfits has 1-based indices, also the last index is *included* in the reading
142
// NOTE: the +0.5 forces a correct cast/ceiling
143
std::vector<long>
first_vertex
{
long
(
m_gridx_values
[
index_min_distance
]+.5) -
long
(
m_grid_offset
),
long
(
m_gridy_values
[
index_min_distance
]+.5) -
long
(
m_grid_offset
)};
144
stack_logger
.debug() <<
"First vertex: ( "
<<
first_vertex
[0] <<
", "
<<
first_vertex
[1] <<
") First vertex alternative: "
<<
145
m_gridx_values
[
index_min_distance
]-
m_grid_offset
<<
" "
<<
m_gridy_values
[
index_min_distance
]-
m_grid_offset
<<
146
" grid offset:"
<<
m_grid_offset
;
147
148
std::vector<long>
last_vertex
{
first_vertex
[0] +
long
(
m_psf_size
) - 1,
first_vertex
[1] +
long
(
m_psf_size
) - 1};
149
std::vector<long>
stride
{1, 1};
150
151
// read out the image
152
std::valarray<SeFloat>
stamp_data
;
153
{
154
std::lock_guard<std::mutex>
lock
(
m_mutex
);
155
m_pFits
->extension(1).read(
stamp_data
,
first_vertex
,
last_vertex
,
stride
);
156
}
157
158
//stack_logger.info() << "DDD ( " << first_vertex[0] << ", " << first_vertex[1] << ") --> ( " << last_vertex[0] << ", " << last_vertex[1] << "): " << stamp_data.size();
159
160
// create and return the psf image
161
return
VectorImage<SeFloat>::create
(
m_psf_size
,
m_psf_size
,
std::begin
(
stamp_data
),
std::end
(
stamp_data
));
162
}
163
164
}
// end SExtractor
stack_logger
static auto stack_logger
Definition
VariablePsfStack.cpp:28
VariablePsfStack.h
std::begin
T begin(T... args)
Elements::Exception
Elements::Logging::getLogger
static Logging getLogger(const std::string &name="")
SourceXtractor::VariablePsfStack::m_ra_values
std::vector< SeFloat > m_ra_values
Definition
VariablePsfStack.h:102
SourceXtractor::VariablePsfStack::m_grid_offset
int m_grid_offset
Definition
VariablePsfStack.h:96
SourceXtractor::VariablePsfStack::m_mutex
std::mutex m_mutex
Definition
VariablePsfStack.h:92
SourceXtractor::VariablePsfStack::getPsf
virtual std::shared_ptr< VectorImage< SeFloat > > getPsf(const std::vector< double > &values) const
Definition
VariablePsfStack.cpp:118
SourceXtractor::VariablePsfStack::selfTest
void selfTest()
Definition
VariablePsfStack.cpp:94
SourceXtractor::VariablePsfStack::m_psf_size
int m_psf_size
Definition
VariablePsfStack.h:95
SourceXtractor::VariablePsfStack::m_nrows
long m_nrows
Definition
VariablePsfStack.h:100
SourceXtractor::VariablePsfStack::setup
void setup(std::shared_ptr< CCfits::FITS > pFits)
Definition
VariablePsfStack.cpp:32
SourceXtractor::VariablePsfStack::mm_pixel_sampling
double mm_pixel_sampling
Definition
VariablePsfStack.h:98
SourceXtractor::VariablePsfStack::m_gridx_values
std::vector< double > m_gridx_values
Definition
VariablePsfStack.h:106
SourceXtractor::VariablePsfStack::m_pFits
std::shared_ptr< CCfits::FITS > m_pFits
Definition
VariablePsfStack.h:93
SourceXtractor::VariablePsfStack::m_x_values
std::vector< SeFloat > m_x_values
Definition
VariablePsfStack.h:104
SourceXtractor::VariablePsfStack::m_gridy_values
std::vector< double > m_gridy_values
Definition
VariablePsfStack.h:107
SourceXtractor::VariablePsfStack::m_dec_values
std::vector< SeFloat > m_dec_values
Definition
VariablePsfStack.h:103
SourceXtractor::VariablePsfStack::m_y_values
std::vector< SeFloat > m_y_values
Definition
VariablePsfStack.h:105
SourceXtractor::VectorImage::create
static std::shared_ptr< VectorImage< T > > create(Args &&... args)
Definition
VectorImage.h:100
std::end
T end(T... args)
std::function
std::lock
T lock(T... args)
std::minmax_element
T minmax_element(T... args)
SourceXtractor
Definition
Aperture.h:30
std::sqrt
T sqrt(T... args)
Generated by
1.10.0