source: trunk/src/Cubes/plots.cc @ 326

Last change on this file since 326 was 321, checked in by MatthewWhiting, 17 years ago
  • Solved most of the problem from ticket #12, where the integrated flux was being calculated differently on different machines. Now casting the spatial size of a detection to a double.
  • Solved ticket #13 as well, to allow compilation when PGPLOT is not available. Included moving cpgIsPS() to mycpgplot.cc.
File size: 11.3 KB
Line 
1// -----------------------------------------------------------------------
2// plots.cc: Functions defining SpectralPlot and ImagePlot classes.
3// -----------------------------------------------------------------------
4// Copyright (C) 2006, Matthew Whiting, ATNF
5//
6// This program is free software; you can redistribute it and/or modify it
7// under the terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 2 of the License, or (at your
9// option) any later version.
10//
11// Duchamp is distributed in the hope that it will be useful, but WITHOUT
12// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14// for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with Duchamp; if not, write to the Free Software Foundation,
18// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
19//
20// Correspondence concerning Duchamp may be directed to:
21//    Internet email: Matthew.Whiting [at] atnf.csiro.au
22//    Postal address: Dr. Matthew Whiting
23//                    Australia Telescope National Facility, CSIRO
24//                    PO Box 76
25//                    Epping NSW 1710
26//                    AUSTRALIA
27// -----------------------------------------------------------------------
28#include <iostream>
29#include <sstream>
30#include <string>
31#include <math.h>
32#include <cpgplot.h>
33#include <param.hh>
34#include <duchamp.hh>
35#include <Utils/mycpgplot.hh>
36#include <Cubes/plots.hh>
37
38using std::stringstream;
39using namespace mycpgplot;
40
41namespace Plot
42{
43
44  //----------------------------------------------------------
45  // SpectralPlot functions
46  //----------------------------------------------------------
47
48  SpectralPlot::SpectralPlot(){
49    paperWidth=a4width/inchToCm - 2*psHoffset;
50    spectraCount=0;
51    numOnPage = 5;
52  };
53
54  SpectralPlot::~SpectralPlot(){};
55  //----------------------------------------------------------
56  int SpectralPlot::setUpPlot(std::string pgDestination){
57    /**
58     * Opens the designated pgplot device.  Scales the paper so that
59     * it fits on an A4 sheet (using known values of the default
60     * pgplot offsets). 
61     *
62     * \param pgDestination The std::string indicating the PGPLOT device to
63     * be written to.
64     *
65     * \return The value returned by mycpgopen. If <= 0, then an error
66     * has occurred.
67     */
68    paperHeight = paperWidth*M_SQRT2;
69    if(paperHeight+2*psVoffset > a4height){
70      paperHeight = a4height - 2*psVoffset;
71      paperWidth = paperHeight / M_SQRT2;
72    }
73    identifier = mycpgopen(pgDestination);
74    if(identifier>0) cpgpap(paperWidth, paperHeight/paperWidth);
75    // make paper size to fit on A4.
76    return identifier;
77  }
78  //----------------------------------------------------------
79  void SpectralPlot::calcCoords(){
80    /**
81     * Calculates the boundaries for the various boxes, in inches measured
82     *  from the lower left corner.
83     * Based on the fact that there are numOnPage spectra shown on each
84     *  page, going down the page in increasing number (given by
85     *  SpectralPlot::spectraCount).
86     */
87    int posOnPage = (numOnPage - (spectraCount%numOnPage))%numOnPage;
88    mainCoords[0] = Plot::spMainX1/inchToCm;
89    mainCoords[1] = Plot::spMainX2/inchToCm;
90    zoomCoords[0] = Plot::spZoomX1/inchToCm;
91    zoomCoords[1] = Plot::spZoomX2/inchToCm;
92    mainCoords[2] = zoomCoords[2] = mapCoords[2] =
93      posOnPage*paperHeight/float(numOnPage) + Plot::spMainY1/inchToCm;
94    mainCoords[3] = zoomCoords[3] = mapCoords[3] =
95      posOnPage*paperHeight/float(numOnPage) + Plot::spMainY2/inchToCm;
96    mapCoords[0]  = Plot::spMapX1/inchToCm;
97    mapCoords[1]  = mapCoords[0] + (mapCoords[3]-mapCoords[2]);
98  }
99  //----------------------------------------------------------
100  void SpectralPlot::gotoHeader(std::string xlabel){
101    /**
102     * Calls calcCoords, to calculate correct coordinates for this spectrum.
103     * Defines the region for the header information, making it centred
104     *  on the page.
105     * Also writes the velocity (x axis) label, given by the string argument.
106     * \param xlabel Label to go on the velocity/spectral axis.
107     */
108    if(spectraCount%numOnPage==0) cpgpage();
109    spectraCount++;
110    calcCoords();
111    cpgvsiz(0., paperWidth, mainCoords[2], mainCoords[3]); 
112    cpgsch(spLabelSize);
113    cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
114  }
115  //----------------------------------------------------------
116  void SpectralPlot::gotoMainSpectrum(float x1, float x2, float y1, float y2, std::string ylabel){
117    /**
118     *  Defines the region for the main spectrum.
119     *  Draws the box, with tick marks, and
120     *   writes the flux (y axis) label, given by the string argument.
121     * \param x1 Minimum X-coordinate of box.
122     * \param x2 Maximum X-coordinate of box.
123     * \param y1 Minimum Y-coordinate of box.
124     * \param y2 Maximum Y-coordinate of box.
125     * \param ylabel Label for the flux (Y) axis.
126     */
127    cpgvsiz(mainCoords[0],mainCoords[1],mainCoords[2],mainCoords[3]);
128    cpgsch(spIndexSize);
129    cpgswin(x1,x2,y1,y2);
130    cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
131    cpgsch(spLabelSize);
132    cpgmtxt("l",Plot::spYlabelOffset,0.5,0.5,ylabel.c_str());
133  }
134  //----------------------------------------------------------
135  void SpectralPlot::gotoZoomSpectrum(float x1, float x2, float y1, float y2){
136    /**
137     *   Defines the region for the zoomed-in part of the spectrum.
138     *   Draws the box, with special tick marks on the bottom axis.
139     * \param x1 Minimum X-coordinate of box.
140     * \param x2 Maximum X-coordinate of box.
141     * \param y1 Minimum Y-coordinate of box.
142     * \param y2 Maximum Y-coordinate of box.
143     */
144    cpgvsiz(zoomCoords[0],zoomCoords[1],zoomCoords[2],zoomCoords[3]);
145    cpgsch(spIndexSize);
146    cpgswin(x1,x2,y1,y2);
147    cpgbox("bc",0.,0,"bcstn1v",0.,0);
148    float lengthL,lengthR,disp,tickpt,step;
149    stringstream label;
150    for(int i=1;i<10;i++){
151      tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
152      switch(i)
153        {
154        case 2:
155        case 8:
156          lengthL = lengthR = 0.5;
157          disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
158          label.str("");
159          label << tickpt;
160          // do a labelled tick mark
161          cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,
162                  disp, 0., label.str().c_str());
163          break;
164        default:
165          label.str("");
166          lengthL = 0.25;
167          lengthR = 0.;
168          disp = 0.;  // not used in this case, but set it anyway.
169          break;
170        }
171      // first the bottom axis, just the ticks
172      if(fabs(tickpt)<(x2-x1)/1.e4) step = 2.*(x2-x1);
173      else step = tickpt;
174      cpgaxis("",
175              tickpt-0.001*(x2-x1), y1,
176              tickpt+0.001*(x2-x1), y1,
177              tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
178              step, -1, lengthL,lengthR, 0.5, disp, 0.);
179      //and now the top -- no labels, just tick marks
180      cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
181    }
182  }
183  //----------------------------------------------------------
184  void SpectralPlot::gotoMap(){
185    cpgvsiz(mapCoords[0],mapCoords[1],mapCoords[2],mapCoords[3]);
186    cpgsch(spIndexSize);
187  }
188  //----------------------------------------------------------
189  void SpectralPlot::drawVelRange(float v1, float v2){
190    /**
191     * Draws two vertical lines at the limits of velocity
192     *  given by the arguments.
193     * \param v1 Minimum velocity.
194     * \param v2 Maximum velocity.
195     */
196    int ci,ls;
197    float dud,min,max;
198    cpgqwin(&dud,&dud,&min,&max);
199    cpgqci(&ci);
200    cpgqls(&ls);
201    cpgsci(DUCHAMP_OBJECT_OUTLINE_COLOUR);
202    cpgsls(DASHED);
203    cpgmove(v1,min);  cpgdraw(v1,max);
204    cpgmove(v2,min);  cpgdraw(v2,max);
205    cpgsci(ci);
206    cpgsls(ls);
207  }
208  //----------------------------------------------------------
209  void SpectralPlot::drawMWRange(float v1, float v2){
210    /**
211     * Draws a box showing the extent of channels masked by the
212     *  Milky Way parameters
213     * \param v1 Minimum velocity of the Milky Way range.
214     * \param v2 Maximum velocity of the Milky Way range.
215     */
216    int ci,fs;
217    float dud,min,max,height;
218    cpgqwin(&dud,&dud,&min,&max);
219    height = max-min;
220    max += 0.01*height;
221    min -= 0.01*height;
222    cpgqci(&ci);
223    cpgqfs(&fs);
224    setDarkGreen();
225    cpgsci(DUCHAMP_MILKY_WAY_COLOUR);
226    cpgsfs(HATCHED);
227    cpgrect(v1,v2,min,max);
228    cpgsfs(OUTLINE);
229    cpgrect(v1,v2,min,max);
230    cpgsci(ci);
231    cpgsfs(fs);
232  }
233
234  //----------------------------------------------------------
235  //----------------------------------------------------------
236  // ImagePlot functions
237  //----------------------------------------------------------
238
239  ImagePlot::ImagePlot(){
240    paperWidth = 7.5;
241    maxPaperHeight = 10.;
242    marginWidth = 0.8;
243    wedgeWidth = 0.7;
244  };
245
246  ImagePlot::~ImagePlot(){};
247  //----------------------------------------------------------
248
249  int ImagePlot::setUpPlot(std::string pgDestination, float x, float y){
250    /**
251     *  Opens a pgplot device and scales it to the correct shape.
252     *  In doing so, the dimensions for the image are set, and the required
253     *   aspect ratios of the image and of the plot are calculated.
254     *  If the resulting image is going to be tall enough to exceed the
255     *   maximum height (given the default width), then scale everything
256     *   down by enough to make the height equal to maxPaperHeight.
257     * \param pgDestination  The string indicating the PGPLOT device to be
258     *   written to.
259     * \param x The length of the X-axis.
260     * \param y The length of the Y-axis.
261     * \return The value returned by mycpgopen: if <= 0, then an error
262     *  has occurred.
263     */
264    xdim = x;
265    ydim = y;
266    imageRatio= ydim / xdim;
267    aspectRatio =  (imageRatio*imageWidth() + 2*marginWidth) / paperWidth;
268    float correction;
269    if((imageRatio*imageWidth() + 2*marginWidth) > maxPaperHeight){
270      correction = maxPaperHeight / (imageRatio*imageWidth()+2*marginWidth);
271      paperWidth *= correction;
272      marginWidth *= correction;
273      wedgeWidth *= correction;
274    }
275    identifier = mycpgopen(pgDestination);
276    if(identifier>0) cpgpap(paperWidth, aspectRatio);
277    return identifier;
278  }
279  //----------------------------------------------------------
280  void ImagePlot::drawMapBox(float x1, float x2, float y1, float y2,
281                             std::string xlabel, std::string ylabel){
282    /**
283     *  Defines the region that the box containing the map is to go in,
284     *  and draws the box with limits given by the arguments.
285     *  Also writes labels on both X- and Y-axes.
286     * \param x1 Minimum X-axis value.
287     * \param x2 Maximum X-axis value.
288     * \param y1 Minimum Y-axis value.
289     * \param y2 Maximum Y-axis value.
290     * \param xlabel The label to be put on the X-axis.
291     * \param ylabel The label to be put on the Y-axis.
292     */
293    cpgvsiz(marginWidth, marginWidth + imageWidth(),
294            marginWidth, marginWidth + (imageWidth()*imageRatio));
295    cpgslw(2);
296    cpgswin(x1,x2,y1,y2);
297    cpgbox("bcst",0.,0,"bcst",0.,0);
298    cpgslw(1);
299    cpgbox("bcnst",0.,0,"bcnst",0.,0);
300    cpglab(xlabel.c_str(), ylabel.c_str(), "");
301  }
302  //----------------------------------------------------------
303  void ImagePlot::makeTitle(std::string title){
304    /**
305     *    Writes the title for the plot, making it centred for the entire
306     *     plot and not just the map.
307     *   \param title String with title for plot.
308     */
309    cpgvstd();
310    cpgmtxt("t", Plot::imTitleOffset, 0.5, 0.5, title.c_str());
311  }
312
313
314}
Note: See TracBrowser for help on using the repository browser.