source: trunk/src/Cubes/plots.hh @ 146

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

A few new things:

  • Made a mycpgplot.hh file, to keep PGPlot-related constants (enum types)

in a standard namespace (so one can do cpgsci(RED) rather than cpgsci(2)...).
Incorporated this into all code that uses pgplot.

  • Improved the outputting of the number of detected objects in the search

functions. Now shows how many have been detected, before they are merged
into the list.

  • Fixed a bug in columns.cc that was incorrectly updating the precision for

negative velocities.

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