Subint.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2010 by Paul Demorest
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 #ifndef __Subint_h
10 #define __Subint_h
11 
12 #include "dsp/TimeDivide.h"
13 #include "dsp/PhaseSeries.h"
14 
15 #include "Phase.h"
16 #include "Callback.h"
17 
18 #define VERBOSE true
19 // #define VERBOSE Op::verbose
20 
21 namespace dsp {
22 
23  class PhaseSeriesUnloader;
24 
26 
35  template <class Op>
36  class Subint : public Op {
37 
38  public:
39 
41  Subint ();
42 
44  ~Subint ();
45 
47  Op* clone () const;
48 
50  void finish ();
51 
58 
61 
64 
66 
68  void set_start_time (const MJD& start_time)
69  { divider.set_start_time (start_time); }
70 
72  MJD get_start_time () const { return divider.get_start_time(); }
73 
75  void set_subint_seconds (double subint_seconds)
76  { divider.set_seconds (subint_seconds); }
77 
79  double get_subint_seconds () const { return divider.get_seconds(); }
80 
82  void set_subint_reference_epoch (const MJD& epoch)
83  { divider.set_reference_epoch (epoch); }
84 
87  { return divider.get_reference_epoch (); }
88 
90  void set_subint_turns (unsigned subint_turns)
91  { divider.set_turns (subint_turns); }
92 
94  unsigned get_subint_turns () const { return unsigned(divider.get_turns());}
95 
96  void set_fractional_pulses (bool flag)
97  { divider.set_fractional_pulses (flag); }
98 
99  void set_reference_phase (double phase)
100  { divider.set_reference_phase (phase); Op::set_reference_phase(phase); }
101 
106 
109 
112 
114  virtual bool keep (PhaseSeries* data) { return true; }
115 
117 
119  const TimeDivide* get_divider () const { return &divider; }
120 
122  void set_cerr (std::ostream& os) const;
123 
124  protected:
125 
127  virtual void unload_partial ();
128 
130  virtual void transformation ();
131 
133  virtual void set_limits (const Observation* input);
134 
137 
140 
142  void prepare ();
143 
145  void zero_output ();
146 
148  bool built;
149 
150  };
151 
152 }
153 
154 #include "dsp/SignalPath.h"
155 #include "dsp/PhaseSeriesUnloader.h"
156 
157 #include "Error.h"
158 
159 //using namespace std;
160 
161 template <class Op>
163 {
164  built = false;
165  std::string orig_name = Op::get_name();
166  Op::set_name("Subint<" + orig_name + ">");
167 }
168 
169 template <class Op>
171 {
172  if (Op::verbose)
173  this->cerr << "dsp::Subint::~Subint" << std::endl;
174 }
175 
176 template <class Op>
178 {
179  if (Op::verbose)
180  this->cerr << "dsp::Subint<Op>::clone" << std::endl;
181  return new Subint<Op>(*this);
182 }
183 
185 template <class Op>
186 void dsp::Subint<Op>::set_cerr (std::ostream& os) const
187 {
188  Op::set_cerr (os);
189  divider.set_cerr (os);
190  if (unloader)
191  unloader->set_cerr (os);
192 }
193 
195 template <class Op>
197 {
198  if (Op::verbose)
199  this->cerr << "dsp::Subint::set_unloader this=" << this
200  << " unloader=" << _unloader << std::endl;
201 
202  unloader = _unloader;
203  if (unloader)
204  unloader->set_cerr (this->cerr);
205 }
206 
207 template <class Op>
209 {
210  if (Op::verbose)
211  this->cerr << "dsp::Subint::prepare call Op::prepare" << std::endl;
212 
213  Op::prepare ();
214 
215  // if unspecified, the first TimeSeries to be folded will define the
216  // start time from which to begin cutting up the observation
217  if (divider.get_start_time() == MJD::zero)
218  {
219  if (Op::verbose)
220  this->cerr << "dsp::Subint::prepare set divider start time="
221  << Op::input->get_start_time() << std::endl;
222 
223  if (Op::input->get_start_time() == MJD::zero)
224  throw Error (InvalidState, "dsp::Subint::prepare",
225  "input start time not set");
226 
227  divider.set_start_time (Op::input->get_start_time());
228  }
229 
230  if (divider.get_turns())
231  {
232  if (Op::has_folding_predictor())
233  {
234  divider.set_predictor (Op::get_folding_predictor());
235  }
236  else
237  {
238  if (Op::verbose)
239  this->cerr << "dsp::Subint::prepare folding period=" << Op::get_folding_period() << std::endl;
240  divider.set_period (Op::get_folding_period());
241  }
242  }
243 
244  built = true;
245 }
246 catch (Error& error)
247 {
248  throw error += "dsp::Subint::prepare";
249 }
250 
251 
252 template <class Op>
254 {
255  if (Op::verbose)
256  this->cerr << "dsp::Subint::transformation" << std::endl;
257 
258  if (divider.get_turns() == 0 && divider.get_seconds() == 0.0)
259  throw Error (InvalidState, "dsp::Subint::tranformation",
260  "sub-integration length not specified");
261 
262  if (!built)
263  prepare ();
264 
265  // flag that the input TimeSeries contains data for another sub-integration
266  bool more_data = true;
267  bool first_division = true;
268 
269  while (more_data)
270  {
271  divider.set_bounds( Op::get_input() );
272 
273  if (!divider.get_fractional_pulses())
274  Op::get_output()->set_ndat_expected( divider.get_division_ndat() );
275 
276  more_data = divider.get_in_next ();
277 
278  if (first_division && divider.get_new_division())
279  {
280  /* A new division has been started and there is still data in
281  the current integration. This is a sign that the current
282  input comes from uncontiguous data, which can arise when
283  processing in parallel. */
284 
285  if (Op::verbose)
286  this->cerr << "dsp::Subint::transformation unload partial (first_division and new division)" << std::endl;
287 
288  unload_partial ();
289  }
290 
291  if (!divider.get_is_valid())
292  continue;
293 
294  Op::transformation ();
295 
296  if (!divider.get_end_reached())
297  continue;
298 
299  if (first_division)
300  {
301  /* When the end of the first division is reached, it is not 100%
302  certain that a complete sub-integration is available */
303 
304  if (Op::verbose)
305  this->cerr << "dsp::Subint::transformation unload partial (first_division of transformation)" << std::endl;
306 
307  unload_partial ();
308  first_division = false;
309  continue;
310  }
311 
312  if (Op::verbose)
313  this->cerr << "dsp::Subint::transformation sub-integration completed" << std::endl;
314 
315  PhaseSeries* result = Op::get_result ();
316 
317  complete.send (result);
318 
319  if (unloader && keep(result))
320  {
321  if (Op::verbose)
322  this->cerr << "dsp::Subint::transformation this=" << this << " unloader=" << unloader.get() << std::endl;
323 
324  unloader->unload (result);
325  zero_output ();
326  }
327  }
328 }
329 catch (Error& error)
330 {
331  throw error += "dsp::Subint::transformation";
332 }
333 
334 
336 template <class Op>
338 {
339  Op::idat_start = divider.get_idat_start ();
340  Op::ndat_fold = divider.get_ndat ();
341 }
342 
343 template <class Op>
345 {
346  Op::finish ();
347 
348  if (Op::get_result()->get_integration_length() != 0)
349  {
350  if (Op::verbose)
351  this->cerr << "dsp::Subint::finish unload_partial" << std::endl;
352 
353  unload_partial ();
354  }
355 
356  if (unloader)
357  {
358  if (Op::verbose)
359  this->cerr << "dsp::Subint::finish call unloader finish" << std::endl;
360 
361  unloader->finish ();
362  }
363 }
364 catch (Error& error)
365 {
366  throw error += "dsp::Subint::finish";
367 }
368 
369 template <class Op>
371 {
372  PhaseSeries* result = Op::get_result ();
373 
374  if (Op::verbose)
375  this->cerr << "dsp::Subint::unload_partial MJD=" << result->get_start_time().printall() << std::endl;
376 
377  if (Op::verbose)
378  this->cerr << "dsp::Subint::unload_partial this=" << (void*) this
379  << " result=" << (void*) result << std::endl;
380 
381  partial.send (result);
382 
383  if (unloader)
384  {
385  if (Op::verbose)
386  this->cerr << "dsp::Subint::unload_partial this=" << this
387  << " unloader=" << unloader.get() << std::endl;
388 
389  unloader->partial (result);
390  }
391 
392  zero_output ();
393 }
394 catch (Error& error)
395 {
396  throw error += "dsp::Subint::unload_partial";
397 }
398 
399 #define SIGNAL_PATH
400 
401 template <class Op>
403 {
404 #ifdef SIGNAL_PATH
405  SignalPath* path = 0;
406  PhaseSeries* out_ptr = Op::output;
407 
408  if (out_ptr->has_extensions())
409  {
410  Extensions* ext = out_ptr->get_extensions();
411  path = ext->get<SignalPath>();
412  }
413 
414  if (path)
415  {
416  if (Op::verbose)
417  this->cerr << "dsp::Subint::zero_output calling SignalPath:reset"
418  << std::endl;
419  path->reset();
420  }
421  else
422 #endif
423  Op::reset();
424 }
425 
426 #endif
MJD get_start_time() const
Get the start time from which to begin counting sub-integrations.
Definition: Subint.h:72
bool built
Flag set when time divider is initialized.
Definition: Subint.h:148
void set_start_time(MJD start_time)
Set the start time at which to begin dividing.
Definition: TimeDivide.C:35
double get_seconds() const
Get the number of seconds in each division.
Definition: TimeDivide.h:52
virtual void transformation()
Folds the TimeSeries data into one or more sub-integrations.
Definition: Subint.h:253
void set_cerr(std::ostream &os) const
Set verbosity ostream.
Definition: Subint.h:186
Contains all Baseband Data Reduction Library classes.
Definition: ASCIIObservation.h:17
Callback< PhaseSeries * > partial
Attach methods to receive partially completed PhaseSeries instances.
Definition: Subint.h:63
void set_subint_turns(unsigned subint_turns)
Set the number of turns to fold into each sub-integration.
Definition: Subint.h:90
MJD get_start_time() const
Get the start time at which to begin dividing.
Definition: TimeDivide.h:46
unsigned get_subint_turns() const
Get the number of turns to fold into each sub-integration.
Definition: Subint.h:94
Stores information about the signal path.
Definition: SignalPath.h:24
double get_subint_seconds() const
Get the number of seconds to fold into each sub-integration.
Definition: Subint.h:79
Data as a function of pulse phase.
Definition: PhaseSeries.h:28
const Extensions * get_extensions() const
Get the Extensions to be communicated to the Archiver class.
Definition: PhaseSeries.C:564
Op * clone() const
Create a clonse.
Definition: Subint.h:177
MJD get_reference_epoch() const
Set the reference epoch (start time of first division)
Definition: TimeDivide.h:58
void set_start_time(const MJD &start_time)
Set the start time from which to begin counting sub-integrations.
Definition: Subint.h:68
void prepare()
Initialize the time divider.
Definition: Subint.h:208
void set_reference_phase(double phase)
Set the reference phase (phase of bin zero)
Definition: TimeDivide.C:106
virtual void set_limits(const Observation *input)
Set the idat_start and ndat_fold attributes.
Definition: Subint.h:337
void set_unloader(PhaseSeriesUnloader *unloader)
Set the file unloader.
Definition: Subint.h:196
void set_seconds(double division_seconds)
Set the number of seconds in each division.
Definition: TimeDivide.C:68
Stores information about digital, band-limited, time-varying signals.
Definition: Observation.h:33
MJD get_subint_reference_epoch() const
Get the start time of the first sub-integration.
Definition: Subint.h:86
void zero_output()
Reset all outputs to null values.
Definition: Subint.h:402
const TimeDivide * get_divider() const
Access to the divider.
Definition: Subint.h:119
Subint()
Constructor.
Definition: Subint.h:162
TimeDivide divider
The time divider.
Definition: Subint.h:139
Base class for things that can unload PhaseSeries data somewhere.
Definition: PhaseSeriesUnloader.h:30
void set_turns(double division_turns)
Set the number of turns in each division.
Definition: TimeDivide.C:78
PhaseSeriesUnloader * get_unloader() const
Get the file unloader.
Definition: Subint.h:111
Reference::To< PhaseSeriesUnloader > unloader
File unloading flag.
Definition: Subint.h:136
double get_turns() const
Get the number of turns in each division.
Definition: TimeDivide.h:64
void reset()
Reset all of the components in the signal path.
Definition: SignalPath.C:73
Unload PhaseSeries data into sub-integrations.
Definition: Subint.h:36
void set_fractional_pulses(bool)
Fold the fractional pulses at the start and end of data.
Definition: TimeDivide.C:113
void set_reference_phase(double phase)
Attach methods to receive completed PhaseSeries instances.
Definition: Subint.h:99
bool has_extensions() const
Return true if Extensions have been set.
Definition: PhaseSeries.C:574
void set_reference_epoch(const MJD &epoch)
Set the reference epoch (start time of first division)
Definition: TimeDivide.h:55
~Subint()
Destructor.
Definition: Subint.h:170
MJD get_start_time() const
Return the start time of the leading edge of the first time sample.
Definition: Observation.h:152
Calculates the boundaries of a division of time.
Definition: TimeDivide.h:28
void finish()
Emit any unfinished profiles.
Definition: Subint.h:344
void set_fractional_pulses(bool flag)
Attach methods to receive completed PhaseSeries instances.
Definition: Subint.h:96
void set_subint_reference_epoch(const MJD &epoch)
Set the start time of the first sub-integration.
Definition: Subint.h:82
Callback< PhaseSeries * > complete
Attach methods to receive completed PhaseSeries instances.
Definition: Subint.h:60
virtual void set_cerr(std::ostream &) const
virtual void unload_partial()
Unload any partially completed integrations.
Definition: Subint.h:370
void set_subint_seconds(double subint_seconds)
Set the number of seconds to fold into each sub-integration.
Definition: Subint.h:75
virtual bool keep(PhaseSeries *data)
Decide wether or not to keep the folded profile.
Definition: Subint.h:114

Generated using doxygen 1.8.17