BandpassPlotter.h
1//-*-C++-*-
2/***************************************************************************
3 *
4 * Copyright (C) 2004 by Willem van Straten
5 * Licensed under the Academic Free License version 2.1
6 *
7 ***************************************************************************/
8
9// psrchive/Util/pgutil/BandpassPlotter.h
10
11#ifndef __fft_BandpassPlotter_h
12#define __fft_BandpassPlotter_h
13
14#include "templates.h"
15#include "true_math.h"
16
17#include <cpgplot.h>
18#include <algorithm>
19
20namespace fft {
21
22 template<class Data, class Info>
23 class BandpassPlotter {
24
25 public:
26
28 BandpassPlotter ()
29 {
30 user_max = user_min = 0;
31 user_fmax = user_fmin = 0;
32
33 ignore_fraction = 0.0;
34
35 logarithmic = false;
36 xlabel_ichan = false;
37 histogram = false;
38
39 title = "Original Bandpass";
40 }
41
43 virtual ~BandpassPlotter() { }
44
46 virtual void plot (Data* data, Info* info) const;
47
49 template<class T>
50 void plot (std::vector< std::vector<T> >& data, double timespan, Info* info) const;
51
53 virtual void preprocess (std::vector<float>& bandpass) const { }
54
56 void set_minmax (float min, float max)
57 { user_min = min; user_max = max; }
58
60 void set_fminmax (float min, float max)
61 {
62 if (!true_math::finite(min) || !true_math::finite(max))
63 throw Error (InvalidParam, "BandpassPlotter::set_fminmax", "min=%f max=%f", min, max);
64 user_fmin = min;
65 user_fmax = max;
66 }
67
69 float ignore_fraction;
70
72 bool logarithmic;
73
75 bool histogram;
76
78 bool xlabel_ichan;
79
80 std::string title;
81
82 protected:
83 float user_min, user_max;
84 float user_fmin, user_fmax;
85
86 };
87
88}
89
90void log (std::vector<float>& data)
91{
92 for (unsigned i=0; i<data.size(); i++)
93 if (data[i] > 0)
94 data[i] = log10 (data[i]);
95 else
96 data[i] = 0.0;
97}
98
99template<class Data, class Info>
100void fft::BandpassPlotter<Data,Info>::plot (Data* data, Info* info) const
101{
102 unsigned ipol, npol = data->get_npol ();
103 unsigned nchan = 0;
104
105 float min = 0;
106 float max = 0;
107 for (ipol=0; ipol<npol; ipol++)
108 {
109 std::vector<float> pband = data->get_passband (ipol);
110
111 this->preprocess (pband);
112 if (logarithmic)
113 log (pband);
114
115 if (ipol == 0)
116 nchan = pband.size();
117
118 minmax (pband, min, max, ipol);
119 }
120
121 if (user_min != user_max)
122 {
123 min = user_min;
124 max = user_max;
125 }
126
127 double freq = info->get_centre_frequency();
128 double bw = info->get_bandwidth();
129
130 double fmin = freq - bw/2;
131 double fmax = freq + bw/2;
132
133 std::string xlabel = "Frequency (MHz)";
134
135 if (xlabel_ichan)
136 {
137 fmin = 0;
138 fmax = nchan;
139 xlabel = "Frequency channel";
140 }
141
142 float wfmin = fmin;
143 float wfmax = fmax;
144
145 if (user_fmin != user_fmax)
146 {
147 std::cerr << "BandpassPlotter set min=" << user_fmin << " max=" << user_fmax << std::endl;
148 wfmin = user_fmin;
149 wfmax = user_fmax;
150 }
151
152 float fbuf = fabs(0.05 * ( wfmax - wfmin ));
153
154 cpgsci(1);
155 cpgswin (wfmin-fbuf, wfmax+fbuf, min, max);
156
157 // std::cerr << "npol=" << npol << std::endl;
158
159 for (unsigned ipol=0; ipol<npol; ipol++)
160 {
161 std::vector<float> pband = data->get_passband (ipol);
162 this->preprocess (pband);
163 if (logarithmic)
164 log (pband);
165
166 // std::cerr << "ipol=" << ipol << " nchan=" << nchan << std::endl;
167
168 double fstep = bw/(nchan-1);
169 if (xlabel_ichan)
170 fstep = 1.0;
171
172 cpgsci(ipol+2);
173
174 std::vector<float> xaxis (nchan);
175 float offset = 0;
176 if (histogram)
177 offset = 0.5;
178
179 for (unsigned ichan=0; ichan<nchan; ichan++)
180 xaxis[ichan] = fmin + (ichan+offset)*fstep;
181
182 float* x = &xaxis[0];
183 float* y = &pband[0];
184
185 if (histogram)
186 cpgbin (nchan, x, y, true);
187 else
188 cpgline (nchan, x, y);
189 }
190
191 cpgsci (1);
192
193 if (logarithmic)
194 {
195 cpgbox("BCNST", 0.0, 0, "BCNSTL2", 0.0, 0);
196 cpglab(xlabel.c_str(), "Logarithmic Scale", title.c_str());
197 }
198 else
199 {
200 cpgbox("BCNST", 0.0, 0, "BCNST", 0.0, 0);
201 cpglab(xlabel.c_str(), "Linear Scale", title.c_str());
202 }
203}
204
205
206template<class Data, class Info>
207template<class T>
208void fft::BandpassPlotter<Data,Info>::plot (std::vector< std::vector<T> >& data,
209 double timespan, Info* info) const
210{
211 unsigned ntime = data.size();
212 unsigned nchan = data[0].size();
213
214 std::vector<float> plotarray (ntime * nchan);
215
216 float min = 0;
217 float max = 0;
218
219 unsigned jchan = 0;
220
221 unsigned ignore_ichan = (unsigned) (ignore_fraction * nchan);
222
223 for (unsigned itime=0; itime<ntime; itime++) {
224 std::vector<float>& pband = data[itime];
225 this->preprocess (pband);
226
227 minmax (pband.begin()+ignore_ichan, pband.end()-ignore_ichan,
228 min, max, itime);
229
230 for (unsigned ichan=0; ichan<nchan; ichan++)
231 plotarray[ichan+jchan] = pband[ichan];
232
233 jchan += nchan;
234 }
235
236 //std::cerr << "min=" << min << " max=" << max << std::endl;
237 float diff = max - min;
238 min -= .1 * diff;
239 max += .1 * diff;
240 //std::cerr << "min=" << min << " max=" << max << std::endl;
241
242 if (user_max)
243 max = user_max;
244
245 double freq = info->get_centre_frequency();
246 double bw = info->get_bandwidth();
247
248 double fmin = freq - bw/2;
249 double fmax = freq + bw/2;
250
251 cpgsci(1);
252 cpgswin(fmin, fmax, 0, timespan);
253 cpgbox("BCNST", 0.0, 0, "BCNST", 0.0, 0);
254 cpglab("Frequency (MHz)", "Time (s)", "Dynamic Spectrum");
255
256 float fstep = bw/nchan;
257 float tstep = timespan/ntime;
258 float tmin = 0.0;
259
260 float offset_fmin = fmin - 0.5*fstep;
261 float offset_tmin = tmin - 0.5*tstep;
262 float trf[6] = {offset_fmin, fstep, 0.0,
263 offset_tmin, 0.0, tstep};
264
265 cpgimag(&plotarray[0], nchan, ntime, 1, nchan, 1, ntime, min, max, trf);
266
267}
268
269#endif

Generated using doxygen 1.14.0