ColdPlasma.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2006-2025 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// psrchive/More/General/Pulsar/ColdPlasma.h
10
11#ifndef __Pulsar_ColdPlasma_h
12#define __Pulsar_ColdPlasma_h
13
14#include "Pulsar/Transformation.h"
15#include "Pulsar/Archive.h"
16#include "Pulsar/Integration.h"
17#include "Pulsar/Profile.h"
18#include "Physical.h"
19
20namespace Pulsar {
21
23
37 template<class Calculator, class History>
38 class ColdPlasma : public Transformation<Integration> {
39
40 public:
41
43 typedef typename Calculator::Return Type;
44
46 ColdPlasma () { name = "ColdPlasma"; }
47
49
50 virtual double get_relative_measure (const Integration*) const = 0;
51
53
54 virtual bool get_relative_corrected (const Integration*) const = 0;
55
57
58 virtual double get_absolute_measure (const Integration*) const = 0;
59
61
62 virtual bool get_absolute_corrected (const Integration*) const = 0;
63
65
66 virtual Type get_identity () const = 0;
67
69
70 virtual void combine (Type& result, const Type& add) const = 0;
71
73 virtual void apply (Integration*, unsigned channel, Type to_be_corrected) = 0;
74
76 virtual void execute (Archive*);
77
80
82 virtual void revert (Archive*);
83
85 void transform (Integration*);
86
88
89 void setup (const Integration*);
90
92
93 virtual void update (const Integration*);
94
96 virtual void set (const Integration* data)
97 { setup (data); update (data); }
98
100 virtual void set_Profile (const Profile* data)
101 { set_frequency( data->get_centre_frequency () ); }
102
104 virtual void set_frequency (double frequency)
105 { relative.set_frequency(frequency); absolute.set_frequency(frequency); }
106
108 /* \post All data will be corrected to the reference frequency */
109 void execute1 (Integration*);
110
112 /* \post All corrections with respect to the reference frequency will be inverted */
113 void revert_relative (Integration*);
114
116 void correct (Integration*, unsigned start_chan, unsigned end_chan, double freq);
117
119 void match (const Integration* reference, Integration* to_be_corrected);
120
122 void set_reference_wavelength (double metres);
125
127 void set_reference_frequency (double MHz);
129 double get_reference_frequency () const;
130
132 void set_delta (const Type& d) { delta = d; }
133
135 Type get_delta () const { return delta; }
136
137 protected:
138
139 friend class Integration;
140
142 void range (Integration*, unsigned start_chan, unsigned end_chan);
143
145 Calculator relative;
146
148 virtual void update_relative (const Integration*);
149
151 Calculator absolute;
152
154 virtual void update_absolute (const Integration*);
155
158
160 std::string name;
161
163 std::string val;
164 };
165}
166
167template<class C, class H>
168void Pulsar::ColdPlasma<C,H>::setup (const Integration* data)
169{
171 relative.set_measure( get_relative_measure(data) );
172
174 std::cerr << "Pulsar::" + name + "::setup lambda="
175 << get_reference_wavelength() << " measure=" << relative.get_measure()
176 << std::endl;
177}
178
179template<class C, class H>
180void Pulsar::ColdPlasma<C,H>::transform (Integration* data) try
181{
182 setup (data);
183 execute1 (data);
184}
185catch (Error& error)
186{
187 throw error += "Pulsar::" + name + "::transform";
188}
189
190template<class C, class H>
192{
193 for (unsigned i=0; i<arch->get_nsubint(); i++)
194 execute1( arch->get_Integration(i) );
195}
196
197template<class C, class H>
199{
200 for (unsigned i=0; i<arch->get_nsubint(); i++)
202}
203
204template<class C, class H>
206{
207 delta = get_identity ();
208
209 for (unsigned i=0; i<arch->get_nsubint(); i++)
210 range (arch->get_Integration(i), 0, arch->get_nchan());
211}
212
213template<class C, class H>
215{
216 relative.set_reference_frequency (MHz);
217}
218
219template<class C, class H>
221{
222 return relative.get_reference_frequency ();
223}
224
225template<class C, class H>
227{
228 relative.set_reference_wavelength (metres);
229}
230
231template<class C, class H>
233{
234 return relative.get_reference_wavelength ();
235}
236
237template<class Calculator, class History>
239try
240{
241 update_relative(data);
242 update_absolute(data);
243}
244catch (Error& error)
245{
246 throw error += "Pulsar::"+name+"::update";
247}
248
249template<class Calculator, class History>
251{
252 double relative_measure = get_relative_measure (data);
253
255 std::cerr << "Pulsar::" + name + "::update_relative measure=" << relative_measure << std::endl;
256
257 relative.set_measure(relative_measure);
258
260
261 if (get_relative_corrected(data))
262 {
263 double corrected_measure = relative_measure;
264
265 auto history = data->template get<History>();
266 if (history && history->get_relative()->get_corrected())
267 {
268 corrected_measure = history->get_relative()->get_measure();
269 double lambda = history->get_relative()->get_reference_wavelength();
270
272 std::cerr << "Pulsar::" + name + "::update_relative corrected"
273 " measure=" << corrected_measure << " lambda=" << lambda << std::endl;
274
275 // calculate the correction due to the new centre frequency, if any
276 relative.set_wavelength( lambda );
277 delta = relative.evaluate();
278 }
279
280 // remaining correction is due to change in corrected measure, if any
281 relative.set_measure(relative_measure - corrected_measure);
282 }
283}
284catch (Error& error)
285{
286 throw error += "Pulsar::"+name+"::update_relative";
287}
288
289template<class Calculator, class History>
291{
292 double absolute_measure = get_absolute_measure (data);
293
295 std::cerr << "Pulsar::" + name + "::update_absolute measure=" << absolute_measure << std::endl;
296
297 absolute.set_measure(absolute_measure);
298 absolute.set_reference_wavelength(0.0);
299
300 if (get_absolute_corrected(data))
301 {
302 double corrected_measure = absolute_measure;
303
304 auto history = data->template get<History>();
305 if (history && history->get_absolute()->get_corrected())
306 {
307 corrected_measure = history->get_absolute()->get_measure();
308 }
309
311 std::cerr << "Pulsar::" + name + "::update_absolute corrected"
312 " measure=" << corrected_measure << std::endl;
313
314 // remaining correction is due to change in corrected measure, if any
315 absolute.set_measure(absolute_measure - corrected_measure);
316 }
317}
318catch (Error& error)
319{
320 throw error += "Pulsar::"+name+"::update_absolute";
321}
322
323template<class C, class History>
324void Pulsar::ColdPlasma<C,History>::execute1 (Integration* data) try
325{
326 update (data);
327
329 std::cerr << "Pulsar::"+name+"::execute1"
330 " relative "+val+"=" << relative.get_measure() <<
331 " reference wavelength=" << get_reference_wavelength() << std::endl;
332
333 range (data, 0, data->get_nchan());
334
335 double relative_measure = get_relative_measure (data);
336 if (relative_measure)
337 {
338 History* history = data->template getadd<History>();
339 history->get_relative()->set_corrected( true );
340 history->get_relative()->set_measure( relative_measure );
341 history->get_relative()->set_reference_wavelength( get_reference_wavelength() );
342 }
343
344 double absolute_measure = get_absolute_measure (data);
345 if (absolute_measure)
346 {
347 History* history = data->template getadd<History>();
348 history->get_absolute()->set_corrected( true );
349 history->get_absolute()->set_measure( absolute_measure );
350 history->get_absolute()->set_reference_wavelength( 0.0 );
351 }
352}
353catch (Error& error)
354{
355 throw error += "Pulsar::"+name+"::execute1";
356}
357
358template<class C, class History>
360{
361 auto history = data->template get<History>();
362 if (!history)
363 throw Error (InvalidState, "Pulsar::" + name + "::revert_relative", "no correction history");
364
365 if (!history->get_relative()->get_corrected())
366 {
368 std::cerr << "Pulsar::" + name + "::revert_relative not corrected" << std::endl;
369 return;
370 }
371
372 relative.set_measure( -history->get_relative()->get_measure() );
373 set_reference_wavelength( history->get_relative()->get_reference_wavelength() );
375
377 std::cerr << "Pulsar::"+name+"::revert_relative"
378 " relative "+val+"=" << relative.get_measure() <<
379 " reference wavelength=" << get_reference_wavelength() << std::endl;
380
381 range (data, 0, data->get_nchan());
382
383 // this should remove the history
384 delete history;
385}
386catch (Error& error)
387{
388 throw error += "Pulsar::"+name+"::revert_relative";
389}
390
392template<class C, class History>
393void Pulsar::ColdPlasma<C,History>::match (const Integration* reference, Integration* to_correct)
394{
395 const History* history = reference->template get<History>();
396 if (!history)
397 throw Error (InvalidState, "Pulsar::" + name + "::match",
398 "reference has no correction history");
399
400 relative.set_measure( history->get_relative()->get_measure() );
401 set_reference_wavelength( history->get_relative()->get_reference_wavelength() );
402
403 execute1( to_correct );
404}
405
417template<class C, class H>
418void Pulsar::ColdPlasma<C,H>::range (Integration* data, unsigned start_chan, unsigned end_chan) try
419{
421 std::cerr << "Pulsar::"+name+"::range "+val
422 << " relative=" << relative.get_measure()
423 << " absolute=" << absolute.get_measure()
424 << " lambda_0=" << get_reference_wavelength() << " m"
425 << " delta=" << delta << std::endl;
426
427 if (relative.get_measure() == 0 && absolute.get_measure() == 0 && delta == get_identity())
428 {
430 std::cerr << "Pulsar::"+name+"::range nothing to correct" << std::endl;
431 return;
432 }
433
434 if (start_chan >= data->get_nchan())
435 throw Error (InvalidRange, "Pulsar::"+name+"::range",
436 "start chan=%d >= nchan=%d", start_chan, data->get_nchan());
437
438 if (end_chan > data->get_nchan())
439 throw Error (InvalidRange, "Pulsar::"+name+"::range",
440 "end chan=%d > nchan=%d", end_chan, data->get_nchan());
441
442 for (unsigned ichan=start_chan; ichan < end_chan; ichan++)
443 {
444 set_frequency( data->get_centre_frequency (ichan) );
445
446 Type result = delta;
447 combine(result, relative.evaluate());
448 combine(result, absolute.evaluate());
449
451 std::cerr << "Pulsar::"+name+"::range ichan=" << ichan
452 << "\n\t relative=" << relative.evaluate()
453 << "\n\t absolute=" << absolute.evaluate() << std::endl;
454
455 apply (data, ichan, result);
456 }
457}
458catch (Error& error)
459{
460 throw error += "Pulsar::"+name+"::range";
461}
462
463
469template<class C, class H>
470void Pulsar::ColdPlasma<C,H>::correct (Integration* subint,
471 unsigned start_chan, unsigned end_chan,
472 double reference_frequency)
473try
474{
475 setup(subint);
476 set_reference_frequency( reference_frequency );
477 update(subint);
478
480 std::cerr << "Pulsar::" + name + "::correct"
481 " reference freq=" << reference_frequency <<
482 " relative measure=" << relative.get_measure() <<
483 " absolute measure=" << absolute.get_measure() << std::endl;
484
485 range (subint, start_chan, end_chan);
486}
487catch (Error& error)
488{
489 throw error += "Pulsar::"+name+"::correct";
490}
491
492
493#endif
ExtensionType * getadd()
Template method returns an Extension of the specified type.
void combine(const Integration *from)
Combine from into this.
Definition Integration_combine.C:28
const ExtensionType * get() const
Template method searches for an Extension of the specified type.
The primary interface to pulsar observational data.
Definition Archive.h:46
virtual unsigned get_nchan() const =0
Get the number of frequency channels used.
Calculator relative
Computes the effect to be corrected with respect to reference frequency.
Definition ColdPlasma.h:145
Type get_delta() const
Get the correction due to a change in reference wavelength.
Definition ColdPlasma.h:135
void match(const Integration *reference, Integration *to_be_corrected)
Correct the second argument as the first argument was corrected.
Definition ColdPlasma.h:393
Calculator::Return Type
Definition ColdPlasma.h:43
double get_reference_wavelength() const
Get the reference wavelength in metres.
Definition ColdPlasma.h:232
std::string val
The name of the correction measure.
Definition ColdPlasma.h:163
double get_reference_frequency() const
Get the reference frequency in MHz.
Definition ColdPlasma.h:220
virtual Type get_identity() const =0
Derived classes must define the identity.
virtual void apply(Integration *, unsigned channel, Type to_be_corrected)=0
Derived classes must define how to apply the correction.
virtual void update_absolute(const Integration *)
update the absolute transformation based on past correction
Definition ColdPlasma.h:290
std::string name
The name to be used in verbose messages.
Definition ColdPlasma.h:160
virtual double get_absolute_measure(const Integration *) const =0
Return the measure to be corrected with respect to infinite frequency.
Type delta
The correction due to a change in reference wavelength.
Definition ColdPlasma.h:157
void just_do_it(Archive *)
Just do the correction (off the books)
Definition ColdPlasma.h:205
virtual bool get_relative_corrected(const Integration *) const =0
Return true if the relative measure has been corrected with respect to centre frequency.
void revert_relative(Integration *)
Undo the relative correction.
Definition ColdPlasma.h:359
virtual void revert(Archive *)
Revert the correction for an entire Archive.
Definition ColdPlasma.h:198
virtual void set_frequency(double frequency)
Set the frequency for which the correction will be computed.
Definition ColdPlasma.h:104
void setup(const Integration *)
Set up internal variables before execution.
Definition ColdPlasma.h:168
void transform(Integration *)
The default correction.
Definition ColdPlasma.h:180
virtual void set(const Integration *data)
Calls setup then update.
Definition ColdPlasma.h:96
void execute1(Integration *)
Execute the correction for the current get_reference_frequency and get_measure.
Definition ColdPlasma.h:324
void set_reference_frequency(double MHz)
Set the reference frequency in MHz.
Definition ColdPlasma.h:214
virtual void combine(Type &result, const Type &add) const =0
Derived classes must define the operator.
virtual void update_relative(const Integration *)
update the relative transformation based on past correction
Definition ColdPlasma.h:250
virtual void set_Profile(const Profile *data)
Set the frequency for which the correction will be computed.
Definition ColdPlasma.h:100
void correct(Integration *, unsigned start_chan, unsigned end_chan, double freq)
Correct the selected range according to effective_measure.
Definition ColdPlasma.h:470
Calculator absolute
Computes the effect to be corrected with respect to infinite frequency.
Definition ColdPlasma.h:151
virtual bool get_absolute_corrected(const Integration *) const =0
Return true if the relative measure has been corrected with respect to centre frequency.
virtual double get_relative_measure(const Integration *) const =0
Return the measure to be corrected with respect to centre frequency.
void range(Integration *, unsigned start_chan, unsigned end_chan)
Execute the correction on the selected range.
Definition ColdPlasma.h:418
ColdPlasma()
Default constructor.
Definition ColdPlasma.h:46
void set_reference_wavelength(double metres)
Set the reference wavelength in metres.
Definition ColdPlasma.h:226
void set_delta(const Type &d)
Set the correction due to a change in reference wavelength.
Definition ColdPlasma.h:132
virtual void update(const Integration *)
update internal variables before execution
Definition ColdPlasma.h:238
virtual void execute(Archive *)
Execute the correction for an entire Archive.
Definition ColdPlasma.h:191
Integration * get_Integration(unsigned subint)
Return pointer to the specified Integration.
Definition IntegrationManager.C:42
virtual unsigned get_nsubint() const =0
Get the number of sub-integrations stored in the file.
Array of Profiles integrated over the same time interval.
Definition Integration.h:37
double get_centre_frequency(unsigned ichan) const
Get the Profile centre frequency attribute of the given channel.
Definition Integration.C:365
virtual unsigned get_nchan() const =0
Get the number of chans.
static unsigned verbose
flag controls the amount output to stderr by Integration methods
Definition Integration.h:42
Any quantity recorded as a function of pulse phase.
Definition Profile.h:40
double get_centre_frequency() const
get the centre frequency (in MHz)
Definition Profile.h:200
static bool verbose
flag controls the amount output to stderr by Profile methods
Definition Profile.h:48
Algorithms that modify data in the Container.
Definition Transformation.h:20
Defines the PSRCHIVE library.
Definition CalSource.h:17

Generated using doxygen 1.14.0