source: tags/release-1.0.2/src/Cubes/plots.hh @ 1112

Last change on this file since 1112 was 110, checked in by Matthew Whiting, 18 years ago

Final update of config-related files, as well as COPYING and README.
Minor fixes to plotting.cc and plots.hh.
mainDuchamp makes use of header info from config.h.
Added a fix to param.cc to get be able to print true/false even when
boolalpha not defined.
Final update to Guide, included Installation instructions.

File size: 11.9 KB
Line 
1#ifndef PLOTS_H
2#define PLOTS_H
3
4#include <iostream>
5#include <sstream>
6#include <string>
7#include <math.h>
8#include <cpgplot.h>
9
10using std::string;
11using std::stringstream;
12
13namespace Plot
14{
15  const float inchToCm=2.54; // Conversion factor from inches to centimetres.
16  const float a4width=21.0;  // A4 width in cm
17  const float a4height=29.7; // A4 height in cm
18  const float psHoffset=0.35; // The default offset applied to ps files by pgplot
19  const float psVoffset=0.25; // The default offset applied to ps files by pgplot
20
21
22  //***************************************************************************
23
24  class SpectralPlot
25  {
26    /**
27     *  SpectralPlot class
28     *    A class to hold the dimensions and set up for the plotting of the spectra
29     *     (including the full spectra, the zoomed in part, and the moment map).
30     *    The physical dimensions (in inches) of the plot and the elements within
31     *     it are stored, based on the assumption that the plot will go on an A4 page.
32     *    Simple accessor functions are provided to enable access to quantities needed
33     *     for pgplot routines.
34     */
35  public:
36    SpectralPlot(){
37      paperWidth=a4width/inchToCm - 2*psHoffset;
38      spectraCount=0;
39      numOnPage = 5;
40      indexSize = 0.6;
41      labelSize = 0.7;
42    };
43    ~SpectralPlot(){};
44
45    int setUpPlot(string pgDestination){
46      /** SpectralPlot::setUpPlot
47       *    Opens the designated pgplot device.
48       *    Scales the paper so that it fits on an A4 sheet (using known values of
49       *     the default pgplot offsets).
50       *    Returns the value returned by cpgopen -- if <= 0, then an error has occurred.
51       */
52      paperHeight = paperWidth*M_SQRT2;
53      if(paperHeight+2*psVoffset > a4height){
54        paperHeight = a4height - 2*psVoffset;
55        paperWidth = paperHeight / M_SQRT2;
56      }
57      int flag = cpgopen(pgDestination.c_str());
58      if(flag>0) cpgpap(paperWidth, paperHeight/paperWidth); // make paper size to fit on A4.
59      return flag;
60    }
61
62    void calcCoords(){
63      /** SpectralPlot::calcCoords()
64       *    Calculates the boundaries for the various boxes, in inches measured
65       *     from the lower left corner.
66       *    Based on the fact that there are numOnPage spectra shown on each page,
67       *     going down the page in increasing number -- given by spectraCount.
68       */
69      int posOnPage = (numOnPage - (spectraCount%numOnPage))%numOnPage;
70      mainCoords[0] = 2.0/inchToCm;
71      mainCoords[1] = 13.7/inchToCm;
72      zoomCoords[0] = 15.0/inchToCm;
73      zoomCoords[1] = 16.8/inchToCm;
74      mainCoords[2] = zoomCoords[2] = mapCoords[2] =
75        posOnPage*paperHeight/float(numOnPage) + 1.8/inchToCm;
76      mainCoords[3] = zoomCoords[3] = mapCoords[3] =
77        posOnPage*paperHeight/float(numOnPage) + 3.8/inchToCm;
78      mapCoords[0]  = 17.0/inchToCm;
79      mapCoords[1]  = mapCoords[0] + (mapCoords[3]-mapCoords[2]);
80   }
81
82    void gotoHeader(string xlabel){
83      /** SpectralPlot::gotoHeader(string)
84       *   Calls calcCoords, to calculate correct coordinates for this spectrum.
85       *   Defines the region for the header information, making it centred
86       *    on the page.
87       *   Also writes the velocity (x axis) label, given by the string argument.
88       */
89      if(spectraCount%numOnPage==0) cpgpage();
90      spectraCount++;
91      calcCoords();
92      cpgvsiz(0., paperWidth, mainCoords[2], mainCoords[3]); 
93      cpgsch(labelSize);
94      cpgmtxt("b",3.,0.5,0.5,xlabel.c_str());
95    }
96
97    /**
98     * Header line functions
99     *  Functions to write the header information above the boxes.
100     *  One for each line (position/velocity, widths & fluxes, pixel coords).
101     */
102    void firstHeaderLine(string line){  cpgmtxt("t",3.8,0.5,0.5,line.c_str());};
103    void secondHeaderLine(string line){ cpgmtxt("t",2.3,0.5,0.5,line.c_str());};
104    void thirdHeaderLine(string line){  cpgmtxt("t",0.8,0.5,0.5,line.c_str());};
105
106    void gotoMainSpectrum(float x1, float x2, float y1, float y2, string ylabel){
107      /** SpectralPlot::gotoMainSpectrum()
108       *   Defines the region for the main spectrum.
109       *   Draws the box, with tick marks, and
110       *    writes the flux (y axis) label, given by the string argument.
111       */
112      cpgvsiz(mainCoords[0],mainCoords[1],mainCoords[2],mainCoords[3]);
113      cpgsch(indexSize);
114      cpgswin(x1,x2,y1,y2);
115      cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
116      cpgsch(labelSize);
117      cpgmtxt("l",4.,0.5,0.5,ylabel.c_str());
118    }
119
120    void gotoZoomSpectrum(float x1, float x2, float y1, float y2){
121      /** SpectralPlot::gotoZoomSpectrum()
122       *   Defines the region for the zoomed-in part of the spectrum.
123       *   Draws the box, with special tick marks on the bottom axis.
124       */
125      cpgvsiz(zoomCoords[0],zoomCoords[1],zoomCoords[2],zoomCoords[3]);
126      cpgsch(indexSize);
127      cpgswin(x1,x2,y1,y2);
128      cpgbox("bc",0.,0,"bcstn1v",0.,0);
129      float lengthL,lengthR,disp,tickpt;
130      stringstream label;
131      for(int i=1;i<10;i++){
132        tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
133        switch(i)
134          {
135          case 2:
136          case 8:
137            lengthL = lengthR = 0.5;
138            disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
139            label.str("");
140            label << tickpt;
141            // do a labelled tick mark
142            cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,disp,0.,label.str().c_str());
143            break;
144          default:
145            label.str("");
146            lengthL = 0.25;
147            lengthR = 0.;
148            disp = 0.;  // not used in this case, but set it anyway.
149            break;
150          }
151        // first the bottom axis, just the tick
152        cpgaxis("",
153                tickpt-0.001*(x2-x1), y1,
154                tickpt+0.001*(x2-x1), y1,
155                tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
156                tickpt, -1, lengthL,lengthR, 0.5, disp, 0.);
157        // and now the top -- no labels, just tick marks
158        cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
159      }
160   }
161   
162    void gotoMap(){
163      /** SpectralPlot::gotoMap()
164       *   Defines the region for the moment map.
165       */
166      cpgvsiz(mapCoords[0],mapCoords[1],mapCoords[2],mapCoords[3]);
167      cpgsch(indexSize);
168    }
169
170    void drawVelRange(float v1, float v2){
171      /** SpectralPlot::drawVelRange(float v1, float v2)
172       *   Draws two vertical lines at the limits of velocity given by the arguments.
173       */
174      int ci,ls;
175      float dud,min,max;
176      cpgqwin(&dud,&dud,&min,&max);
177      cpgqci(&ci);
178      cpgqls(&ls);
179      cpgsci(4);
180      cpgsls(2);
181      cpgmove(v1,min);  cpgdraw(v1,max);
182      cpgmove(v2,min);  cpgdraw(v2,max);
183      cpgsci(ci);
184      cpgsls(ls);
185    }
186   
187    void drawMWRange(float v1, float v2){
188      /** SpectralPlot::drawMWRange(float v1, float v2)
189       *   Draws a box showing the extent of channels masked by the Milky Way parameters
190       */
191      int ci,fs;
192      float dud,min,max,height;
193      cpgqwin(&dud,&dud,&min,&max);
194      height = max-min;
195      max += 0.01*height;
196      min -= 0.01*height;
197      cpgqci(&ci);
198      cpgqfs(&fs);
199      cpgscr(16,0.,0.7,0.);
200      cpgsci(9);
201      cpgsfs(3);
202      cpgrect(v1,v2,min,max);
203      cpgsfs(2);
204      cpgrect(v1,v2,min,max);
205      cpgsci(ci);
206      cpgsfs(fs);
207    }
208   
209    int   getNumOnPage(){return numOnPage;};
210    void  setNumOnPage(int i){numOnPage=i;};
211    float getPaperWidth(){return paperWidth;};
212    void  setPaperWidth(float f){paperWidth=f;};
213    float getPaperHeight(){return paperHeight;};
214    void  setPaperHeight(float f){paperHeight=f;};
215
216  private:
217    int numOnPage;              // Number of spectra to put on one page.
218    int spectraCount;           // Number of spectra done so far -- where on the page?
219    float mainCoords[4];        // Boundaries for the main spectrum [inches]
220    float zoomCoords[4];        // Boundaries for the zoomed-in spectrum [inches]
221    float mapCoords[4];         // Boundaries for the map box [inches]
222    float paperWidth;           // Width of the plottable region of the paper [inches]
223    float paperHeight;          // Height of the plottable region of the paper [inches]
224    float indexSize;            // PGPlot character height for tick mark labels
225    float labelSize;            // PGPlot character height for axis labels.
226   
227  };
228
229  //***************************************************************************
230
231  class ImagePlot
232  {
233    /**
234     *  ImagePlot class
235     *    A class to hold the dimensions and set up for the plots used by the two
236     *     functions below.
237     *    The physical dimensions (in inches) of the plot and the elements within
238     *     it are stored, including maximum widths and heights (so that the plot will
239     *     fit on an A4 page).
240     *    Simple accessor functions are provided to enable access to quantities needed
241     *     for pgplot routines.
242     */
243  public:
244    ImagePlot(){
245      paperWidth = 7.5; maxPaperHeight = 10.; marginWidth = 0.8; wedgeWidth = 0.7;
246    };
247    ~ImagePlot(){};
248 
249    int  setUpPlot(string pgDestination, float x, float y){
250      /**
251       * setUpPlot(string pgDestination, float x, float y)
252       *  Opens a pgplot device and scales it to the correct shape.
253       *  In doing so, the dimensions for the image are set, and the required aspect ratios
254       *   of the image and of the plot are calculated.
255       *  If the resulting image is going to be tall enough to exceed the maximum height
256       *   (given the default width), then scale everything down by enough to make the
257       *   height equal to maxPaperHeight.
258       *  Returns the value returned by cpgopen -- if <= 0, then an error has occurred.
259       */
260      xdim = x;
261      ydim = y;
262      imageRatio= ydim / xdim;
263      aspectRatio =  (imageRatio*imageWidth() + 2*marginWidth) / paperWidth;
264      if((imageRatio*imageWidth() + 2*marginWidth) > maxPaperHeight){
265        float correction = maxPaperHeight / (imageRatio*imageWidth() + 2*marginWidth);
266        paperWidth *= correction;
267        marginWidth *= correction;
268        wedgeWidth *= correction;
269      }
270      int flag = cpgopen(pgDestination.c_str());
271      if(flag>0) cpgpap(paperWidth, aspectRatio);
272      return flag;
273    }
274
275    void  drawMapBox(float x1, float x2, float y1, float y2, string xlabel, string ylabel){
276      /**
277       * drawMapBox()
278       *  Defines the region that the box containing the map is to go in,
279       *  and draws the box with limits given by the arguments.
280       *  The labels for the x and y axes are also given as arguments.
281       */
282      cpgvsiz(marginWidth, marginWidth + imageWidth(),
283              marginWidth, marginWidth + (imageWidth()*imageRatio));
284      cpgslw(2);
285      cpgswin(x1,x2,y1,y2);
286      cpgbox("bcst",0.,0,"bcst",0.,0);
287      cpgslw(1);
288      cpgbox("bcnst",0.,0,"bcnst",0.,0);
289      cpglab(xlabel.c_str(), ylabel.c_str(), "");
290    }
291    void  makeTitle(string title){
292      /**
293       *  makeTitle(string)
294       *    Writes the title for the plot, making it centred for the entire plot
295       *    and not just the map.
296       */
297      cpgvstd();
298      cpgmtxt("t", 2.7, 0.5, 0.5, title.c_str());
299    }
300
301    float imageWidth(){
302      /**
303       * imageWidth()
304       *   Returns the calculated total width of the image part of the plot [inches]
305       */
306      return paperWidth - 2*marginWidth - wedgeWidth;
307    };       
308
309    float cmToCoord(float cm){return (cm/inchToCm) * ydim / (imageWidth()*imageRatio);};
310    float getMargin()     {return marginWidth;};
311    float getPaperWidth() {return paperWidth;};
312    float getImageHeight(){return imageWidth()*imageRatio;};
313    float getAspectRatio(){return aspectRatio;};
314
315
316  private:
317    float paperWidth;       // Default (maximum) width of "paper" [inches]
318    float maxPaperHeight;   // Maximum allowed height of paper [inches]
319    float marginWidth;      // Width allowed for margins around main plot (ie. label & numbers) [inches]
320    float wedgeWidth;       // Width allowed for placement of wedge on right hand side of plot. [inches]
321    float imageRatio;       // Aspect ratio of the image only (ie. y-value range / x-value range).
322    float aspectRatio;      // Aspect ratio of whole plot.
323    float xdim;             // Width of main plot, in display units.
324    float ydim;             // Height of main plot, in display units.
325  };
326
327}
328
329#endif
330
Note: See TracBrowser for help on using the repository browser.