source: tags/release-1.1/src/Cubes/plots.cc @ 1391

Last change on this file since 1391 was 299, checked in by Matthew Whiting, 17 years ago

Adding distribution text at the start of each file...

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 <Utils/mycpgplot.hh>
35#include <Cubes/plots.hh>
36
37using std::stringstream;
38using namespace mycpgplot;
39
40namespace Plot
41{
42
43  //----------------------------------------------------------
44  // SpectralPlot functions
45  //----------------------------------------------------------
46
47  SpectralPlot::SpectralPlot(){
48    paperWidth=a4width/inchToCm - 2*psHoffset;
49    spectraCount=0;
50    numOnPage = 5;
51  };
52
53  SpectralPlot::~SpectralPlot(){};
54  //----------------------------------------------------------
55  int SpectralPlot::setUpPlot(std::string pgDestination){
56    /**
57     * Opens the designated pgplot device.  Scales the paper so that
58     * it fits on an A4 sheet (using known values of the default
59     * pgplot offsets). 
60     *
61     * \param pgDestination The std::string indicating the PGPLOT device to
62     * be written to.
63     *
64     * \return The value returned by cpgopen. If <= 0, then an error
65     * has occurred.
66     */
67    paperHeight = paperWidth*M_SQRT2;
68    if(paperHeight+2*psVoffset > a4height){
69      paperHeight = a4height - 2*psVoffset;
70      paperWidth = paperHeight / M_SQRT2;
71    }
72    identifier = cpgopen(pgDestination.c_str());
73    if(identifier>0) cpgpap(paperWidth, paperHeight/paperWidth);
74    // make paper size to fit on A4.
75    return identifier;
76  }
77  //----------------------------------------------------------
78  void SpectralPlot::calcCoords(){
79    /**
80     * Calculates the boundaries for the various boxes, in inches measured
81     *  from the lower left corner.
82     * Based on the fact that there are numOnPage spectra shown on each
83     *  page, going down the page in increasing number (given by
84     *  SpectralPlot::spectraCount).
85     */
86    int posOnPage = (numOnPage - (spectraCount%numOnPage))%numOnPage;
87    mainCoords[0] = Plot::spMainX1/inchToCm;
88    mainCoords[1] = Plot::spMainX2/inchToCm;
89    zoomCoords[0] = Plot::spZoomX1/inchToCm;
90    zoomCoords[1] = Plot::spZoomX2/inchToCm;
91    mainCoords[2] = zoomCoords[2] = mapCoords[2] =
92      posOnPage*paperHeight/float(numOnPage) + Plot::spMainY1/inchToCm;
93    mainCoords[3] = zoomCoords[3] = mapCoords[3] =
94      posOnPage*paperHeight/float(numOnPage) + Plot::spMainY2/inchToCm;
95    mapCoords[0]  = Plot::spMapX1/inchToCm;
96    mapCoords[1]  = mapCoords[0] + (mapCoords[3]-mapCoords[2]);
97  }
98  //----------------------------------------------------------
99  void SpectralPlot::gotoHeader(std::string xlabel){
100    /**
101     * Calls calcCoords, to calculate correct coordinates for this spectrum.
102     * Defines the region for the header information, making it centred
103     *  on the page.
104     * Also writes the velocity (x axis) label, given by the string argument.
105     * \param xlabel Label to go on the velocity/spectral axis.
106     */
107    if(spectraCount%numOnPage==0) cpgpage();
108    spectraCount++;
109    calcCoords();
110    cpgvsiz(0., paperWidth, mainCoords[2], mainCoords[3]); 
111    cpgsch(spLabelSize);
112    cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
113  }
114  //----------------------------------------------------------
115  void SpectralPlot::gotoMainSpectrum(float x1, float x2, float y1, float y2, std::string ylabel){
116    /**
117     *  Defines the region for the main spectrum.
118     *  Draws the box, with tick marks, and
119     *   writes the flux (y axis) label, given by the string argument.
120     * \param x1 Minimum X-coordinate of box.
121     * \param x2 Maximum X-coordinate of box.
122     * \param y1 Minimum Y-coordinate of box.
123     * \param y2 Maximum Y-coordinate of box.
124     * \param ylabel Label for the flux (Y) axis.
125     */
126    cpgvsiz(mainCoords[0],mainCoords[1],mainCoords[2],mainCoords[3]);
127    cpgsch(spIndexSize);
128    cpgswin(x1,x2,y1,y2);
129    cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
130    cpgsch(spLabelSize);
131    cpgmtxt("l",Plot::spYlabelOffset,0.5,0.5,ylabel.c_str());
132  }
133  //----------------------------------------------------------
134  void SpectralPlot::gotoZoomSpectrum(float x1, float x2, float y1, float y2){
135    /**
136     *   Defines the region for the zoomed-in part of the spectrum.
137     *   Draws the box, with special tick marks on the bottom axis.
138     * \param x1 Minimum X-coordinate of box.
139     * \param x2 Maximum X-coordinate of box.
140     * \param y1 Minimum Y-coordinate of box.
141     * \param y2 Maximum Y-coordinate of box.
142     */
143    cpgvsiz(zoomCoords[0],zoomCoords[1],zoomCoords[2],zoomCoords[3]);
144    cpgsch(spIndexSize);
145    cpgswin(x1,x2,y1,y2);
146    cpgbox("bc",0.,0,"bcstn1v",0.,0);
147    float lengthL,lengthR,disp,tickpt,step;
148    stringstream label;
149    for(int i=1;i<10;i++){
150      tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
151      switch(i)
152        {
153        case 2:
154        case 8:
155          lengthL = lengthR = 0.5;
156          disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
157          label.str("");
158          label << tickpt;
159          // do a labelled tick mark
160          cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,
161                  disp, 0., label.str().c_str());
162          break;
163        default:
164          label.str("");
165          lengthL = 0.25;
166          lengthR = 0.;
167          disp = 0.;  // not used in this case, but set it anyway.
168          break;
169        }
170      // first the bottom axis, just the ticks
171      if(fabs(tickpt)<(x2-x1)/1.e4) step = 2.*(x2-x1);
172      else step = tickpt;
173      cpgaxis("",
174              tickpt-0.001*(x2-x1), y1,
175              tickpt+0.001*(x2-x1), y1,
176              tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
177              step, -1, lengthL,lengthR, 0.5, disp, 0.);
178      //and now the top -- no labels, just tick marks
179      cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
180    }
181  }
182  //----------------------------------------------------------
183  void SpectralPlot::gotoMap(){
184    cpgvsiz(mapCoords[0],mapCoords[1],mapCoords[2],mapCoords[3]);
185    cpgsch(spIndexSize);
186  }
187  //----------------------------------------------------------
188  void SpectralPlot::drawVelRange(float v1, float v2){
189    /**
190     * Draws two vertical lines at the limits of velocity
191     *  given by the arguments.
192     * \param v1 Minimum velocity.
193     * \param v2 Maximum velocity.
194     */
195    int ci,ls;
196    float dud,min,max;
197    cpgqwin(&dud,&dud,&min,&max);
198    cpgqci(&ci);
199    cpgqls(&ls);
200    cpgsci(BLUE);
201    cpgsls(DASHED);
202    cpgmove(v1,min);  cpgdraw(v1,max);
203    cpgmove(v2,min);  cpgdraw(v2,max);
204    cpgsci(ci);
205    cpgsls(ls);
206  }
207  //----------------------------------------------------------
208  void SpectralPlot::drawMWRange(float v1, float v2){
209    /**
210     * Draws a box showing the extent of channels masked by the
211     *  Milky Way parameters
212     * \param v1 Minimum velocity of the Milky Way range.
213     * \param v2 Maximum velocity of the Milky Way range.
214     */
215    int ci,fs;
216    float dud,min,max,height;
217    cpgqwin(&dud,&dud,&min,&max);
218    height = max-min;
219    max += 0.01*height;
220    min -= 0.01*height;
221    cpgqci(&ci);
222    cpgqfs(&fs);
223    setDarkGreen();
224    cpgsci(DARKGREEN);
225    cpgsfs(HATCHED);
226    cpgrect(v1,v2,min,max);
227    cpgsfs(OUTLINE);
228    cpgrect(v1,v2,min,max);
229    cpgsci(ci);
230    cpgsfs(fs);
231  }
232
233  //----------------------------------------------------------
234  //----------------------------------------------------------
235  // ImagePlot functions
236  //----------------------------------------------------------
237
238  ImagePlot::ImagePlot(){
239    paperWidth = 7.5;
240    maxPaperHeight = 10.;
241    marginWidth = 0.8;
242    wedgeWidth = 0.7;
243  };
244
245  ImagePlot::~ImagePlot(){};
246  //----------------------------------------------------------
247
248  int ImagePlot::setUpPlot(std::string pgDestination, float x, float y){
249    /**
250     *  Opens a pgplot device and scales it to the correct shape.
251     *  In doing so, the dimensions for the image are set, and the required
252     *   aspect ratios of the image and of the plot are calculated.
253     *  If the resulting image is going to be tall enough to exceed the
254     *   maximum height (given the default width), then scale everything
255     *   down by enough to make the height equal to maxPaperHeight.
256     * \param pgDestination  The string indicating the PGPLOT device to be
257     *   written to.
258     * \param x The length of the X-axis.
259     * \param y The length of the Y-axis.
260     * \return The value returned by cpgopen: if <= 0, then an error
261     *  has occurred.
262     */
263    xdim = x;
264    ydim = y;
265    imageRatio= ydim / xdim;
266    aspectRatio =  (imageRatio*imageWidth() + 2*marginWidth) / paperWidth;
267    float correction;
268    if((imageRatio*imageWidth() + 2*marginWidth) > maxPaperHeight){
269      correction = maxPaperHeight / (imageRatio*imageWidth()+2*marginWidth);
270      paperWidth *= correction;
271      marginWidth *= correction;
272      wedgeWidth *= correction;
273    }
274    identifier = cpgopen(pgDestination.c_str());
275    if(identifier>0) cpgpap(paperWidth, aspectRatio);
276    return identifier;
277  }
278  //----------------------------------------------------------
279  void ImagePlot::drawMapBox(float x1, float x2, float y1, float y2,
280                             std::string xlabel, std::string ylabel){
281    /**
282     *  Defines the region that the box containing the map is to go in,
283     *  and draws the box with limits given by the arguments.
284     *  Also writes labels on both X- and Y-axes.
285     * \param x1 Minimum X-axis value.
286     * \param x2 Maximum X-axis value.
287     * \param y1 Minimum Y-axis value.
288     * \param y2 Maximum Y-axis value.
289     * \param xlabel The label to be put on the X-axis.
290     * \param ylabel The label to be put on the Y-axis.
291     */
292    cpgvsiz(marginWidth, marginWidth + imageWidth(),
293            marginWidth, marginWidth + (imageWidth()*imageRatio));
294    cpgslw(2);
295    cpgswin(x1,x2,y1,y2);
296    cpgbox("bcst",0.,0,"bcst",0.,0);
297    cpgslw(1);
298    cpgbox("bcnst",0.,0,"bcnst",0.,0);
299    cpglab(xlabel.c_str(), ylabel.c_str(), "");
300  }
301  //----------------------------------------------------------
302  void ImagePlot::makeTitle(std::string title){
303    /**
304     *    Writes the title for the plot, making it centred for the entire
305     *     plot and not just the map.
306     *   \param title String with title for plot.
307     */
308    cpgvstd();
309    cpgmtxt("t", Plot::imTitleOffset, 0.5, 0.5, title.c_str());
310  }
311
312
313}
Note: See TracBrowser for help on using the repository browser.