4 #ifndef DP3_COMMON_DYNSPEC_WRITER_H_
5 #define DP3_COMMON_DYNSPEC_WRITER_H_
7 #include <aocommon/fits/fitsbase.h>
8 #include <aocommon/fits/fitswriter.h>
9 #include <aocommon/uvector.h>
33 time_resolution_(0.0),
35 frequency_resolution_(0.0),
40 origin_comment_(
"DP3/DynSpec - dynamic spectrum extracter"),
44 if (file_pointer !=
nullptr) {
46 fits_close_file(file_pointer, &status);
50 template <
typename NumType>
51 void Write(
const std::string& filename,
const NumType* image) {
53 if (file_pointer !=
nullptr) {
54 fits_close_file(file_pointer, &status);
55 file_pointer =
nullptr;
58 fits_create_file(&file_pointer, (std::string(
"!") + filename).c_str(),
60 checkStatus(status, filename);
62 writeHeaders(file_pointer, filename);
64 long first_pixel[3] = {1, 1, 1};
65 writeImage(file_pointer, filename, image, first_pixel);
67 fits_close_file(file_pointer, &status);
68 checkStatus(status, filename);
69 file_pointer =
nullptr;
73 double obs_start_time) {
75 time_resolution_ = time_resolution;
76 obs_date_ = obs_start_time;
80 double reference_frequency) {
81 n_channels_ = n_channels;
82 frequency_resolution_ = frequency_resolution;
83 frequency_ = reference_frequency;
87 n_stokes_ = n_stokes_parameters;
91 object_name_ = object_name;
99 void SetOrigin(
const std::string& origin,
const std::string& comment) {
101 origin_comment_ = comment;
104 void SetObsId(
const std::string& obs_id) { obs_id_ = obs_id; }
107 void writeHeaders(fitsfile*& fptr,
const std::string& filename)
const {
109 int bitPixInt = FLOAT_IMG;
110 std::vector<long> naxes(3);
112 naxes[1] = n_channels_;
113 naxes[2] = n_stokes_;
116 fits_create_img(fptr, bitPixInt, naxes.size(), naxes.data(), &status);
117 checkStatus(status, filename);
118 const double zero = 0.0;
119 const double one = 1.0;
120 fits_write_key(fptr, TDOUBLE,
"BSCALE", (
void*)&one,
"", &status);
121 checkStatus(status, filename);
122 fits_write_key(fptr, TDOUBLE,
"BZERO", (
void*)&zero,
"", &status);
123 checkStatus(status, filename);
125 fits_write_key(fptr, TSTRING,
"BUNIT", (
void*)
"JY",
"Units are in Jansky",
127 checkStatus(status, filename);
129 if (!telescope_name_.empty()) {
130 fits_write_key(fptr, TSTRING,
"TELESCOP", (
void*)telescope_name_.c_str(),
132 checkStatus(status, filename);
134 if (!object_name_.empty()) {
135 fits_write_key(fptr, TSTRING,
"OBJECT", (
void*)object_name_.c_str(),
"",
137 checkStatus(status, filename);
139 if (!obs_id_.empty()) {
140 fits_write_key(fptr, TSTRING,
"OBSID", (
void*)obs_id_.c_str(),
141 "Observation ID", &status);
142 checkStatus(status, filename);
144 fits_write_key(fptr, TSTRING,
"ORIGIN", (
void*)origin_.c_str(),
145 origin_comment_.c_str(), &status);
146 checkStatus(status, filename);
149 fits_write_key(fptr, TSTRING,
"CTYPE1", (
void*)
"TIME",
"", &status);
150 checkStatus(status, filename);
151 fits_write_key(fptr, TDOUBLE,
"CRPIX1", (
void*)&one,
"", &status);
152 checkStatus(status, filename);
153 fits_write_key(fptr, TDOUBLE,
"CRVAL1", (
void*)&obs_date_,
"", &status);
154 checkStatus(status, filename);
155 fits_write_key(fptr, TDOUBLE,
"CDELT1", (
void*)&time_resolution_,
"",
157 checkStatus(status, filename);
158 fits_write_key(fptr, TSTRING,
"CUNIT1", (
void*)
"s",
"", &status);
159 checkStatus(status, filename);
162 fits_write_key(fptr, TSTRING,
"CTYPE2", (
void*)
"FREQ",
"", &status);
163 checkStatus(status, filename);
164 fits_write_key(fptr, TDOUBLE,
"CRPIX2", (
void*)&one,
"", &status);
165 checkStatus(status, filename);
166 fits_write_key(fptr, TDOUBLE,
"CRVAL2", (
void*)&frequency_,
"", &status);
167 checkStatus(status, filename);
168 fits_write_key(fptr, TDOUBLE,
"CDELT2", (
void*)&frequency_resolution_,
"",
170 checkStatus(status, filename);
171 fits_write_key(fptr, TSTRING,
"CUNIT2", (
void*)
"Hz",
"", &status);
172 checkStatus(status, filename);
175 fits_write_key(fptr, TSTRING,
"CTYPE3", (
void*)
"STOKES",
"", &status);
176 checkStatus(status, filename);
177 fits_write_key(fptr, TDOUBLE,
"CRPIX3", (
void*)&one,
"", &status);
178 checkStatus(status, filename);
179 fits_write_key(fptr, TDOUBLE,
"CRVAL3", (
void*)&one,
"", &status);
180 checkStatus(status, filename);
181 fits_write_key(fptr, TDOUBLE,
"CDELT3", (
void*)&one,
"", &status);
182 checkStatus(status, filename);
183 fits_write_key(fptr, TSTRING,
"CUNIT3", (
void*)
"",
"", &status);
184 checkStatus(status, filename);
187 int year, month, day, hour, min, sec, deciSec;
188 aocommon::FitsWriter::ModifiedJulianDateToYMD(obs_date_, year, month, day);
189 aocommon::FitsWriter::MJDToHMS(obs_date_, hour, min, sec, deciSec);
191 std::sprintf(dateStr,
"%d-%02d-%02dT%02d:%02d:%02d.%01d", year, month, day,
192 hour, min, sec, deciSec);
193 fits_write_key(fptr, TSTRING,
"DATE-OBS", (
void*)dateStr,
"", &status);
194 checkStatus(status, filename);
197 double ra_deg = (object_ra_ / M_PI) * 180.0,
198 dec_deg = (object_dec_ / M_PI) * 180.0;
199 fits_write_key(fptr, TDOUBLE,
"OBJ-RA", (
void*)&ra_deg,
200 "Target right ascension in degrees", &status);
201 checkStatus(status, filename);
202 fits_write_key(fptr, TDOUBLE,
"OBJ-DEC", (
void*)&dec_deg,
203 "Target declination in degrees", &status);
204 checkStatus(status, filename);
207 void writeImage(fitsfile* fptr,
const std::string& filename,
208 const double* image,
long* currentPixel)
const {
209 double null_value = std::numeric_limits<double>::max();
211 const size_t total_size = n_times_ * n_channels_ * n_stokes_;
212 fits_write_pixnull(fptr, TDOUBLE, currentPixel, total_size,
213 const_cast<double*
>(image), &null_value, &status);
214 checkStatus(status, filename);
217 void writeImage(fitsfile* fptr,
const std::string& filename,
218 const float* image,
long* currentPixel)
const {
219 float null_value = std::numeric_limits<float>::max();
221 const size_t total_size = n_times_ * n_channels_ * n_stokes_;
222 fits_write_pixnull(fptr, TFLOAT, currentPixel, total_size,
223 const_cast<float*
>(image), &null_value, &status);
224 checkStatus(status, filename);
227 template <
typename NumType>
228 void writeImage(fitsfile* fptr,
const std::string& filename,
229 const NumType* image,
long* currentPixel)
const {
230 double null_value = std::numeric_limits<double>::max();
232 const size_t total_size = n_times_ * n_channels_ * n_stokes_;
233 std::vector<double> copy(total_size);
234 for (
size_t i = 0; i != total_size; ++i) copy[i] = image[i];
235 fits_write_pixnull(fptr, TDOUBLE, currentPixel, total_size, ©[0],
236 &null_value, &status);
237 checkStatus(status, filename);
240 fitsfile* file_pointer =
nullptr;
241 std::size_t n_times_;
242 std::size_t n_channels_;
243 std::size_t n_stokes_;
247 double time_resolution_;
249 double frequency_resolution_;
250 std::string telescope_name_;
251 std::string observer_;
252 std::string object_name_;
254 std::string origin_comment_;
Definition: DynSpecFitsWriter.h:24
void SetObsId(const std::string &obs_id)
Definition: DynSpecFitsWriter.h:104
void SetOrigin(const std::string &origin, const std::string &comment)
Definition: DynSpecFitsWriter.h:99
void SetObjectName(const std::string &object_name)
Definition: DynSpecFitsWriter.h:90
DynSpecFitsWriter()
Definition: DynSpecFitsWriter.h:26
void InitializeTimeAxis(size_t n_times, double time_resolution, double obs_start_time)
Definition: DynSpecFitsWriter.h:72
void InitializeFrequencyAxis(size_t n_channels, double frequency_resolution, double reference_frequency)
Definition: DynSpecFitsWriter.h:79
void InitializeStokesAxis(size_t n_stokes_parameters)
Definition: DynSpecFitsWriter.h:86
void Write(const std::string &filename, const NumType *image)
Definition: DynSpecFitsWriter.h:51
~DynSpecFitsWriter()
Definition: DynSpecFitsWriter.h:43
void SetObjectCoordinates(double ra, double dec)
Definition: DynSpecFitsWriter.h:94
Definition: BaselineSelection.h:20