source: tags/release-1.1.12/src/Cubes/plots.cc @ 1455

Last change on this file since 1455 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 20.1 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 <duchamp/param.hh>
34#include <duchamp/duchamp.hh>
35#include <duchamp/Utils/mycpgplot.hh>
36#include <duchamp/Cubes/plots.hh>
37
38using std::stringstream;
39using namespace mycpgplot;
40
41namespace duchamp
42{
43
44  namespace Plot
45  {
46
47    //----------------------------------------------------------
48    // SpectralPlot functions
49    //----------------------------------------------------------
50
51    SpectralPlot::SpectralPlot(){
52      this->paperWidth=a4width/inchToCm - 2*psHoffset;
53      this->spectraCount=0;
54      this->numOnPage = 5;
55    }
56
57    SpectralPlot::~SpectralPlot(){}
58
59    SpectralPlot::SpectralPlot(const SpectralPlot& p)
60    {
61      operator=(p);
62    }
63
64    SpectralPlot& SpectralPlot::operator=(const SpectralPlot& p)
65    {
66      if(this==&p) return *this;
67      this->numOnPage = p.numOnPage;
68      this->spectraCount = p.spectraCount; 
69      for(int i=0;i<4;i++) this->mainCoords[i] = p.mainCoords[i];
70      for(int i=0;i<4;i++) this->zoomCoords[i] = p.zoomCoords[i];
71      for(int i=0;i<4;i++) this->mapCoords[i] = p.mapCoords[i];
72      this->paperWidth = p.paperWidth;   
73      this->paperHeight = p.paperHeight;   
74      this->identifier = p.identifier;   
75      return *this;
76    }
77
78    //----------------------------------------------------------
79    int SpectralPlot::setUpPlot(std::string pgDestination)
80    {
81      ///  @details
82      /// Opens the designated pgplot device.  Scales the paper so that
83      /// it fits on an A4 sheet (using known values of the default
84      /// pgplot offsets). 
85      ///
86      /// \param pgDestination The std::string indicating the PGPLOT device to
87      /// be written to.
88      ///
89      /// \return The value returned by mycpgopen. If <= 0, then an error
90      /// has occurred.
91
92      this->paperHeight = this->paperWidth*M_SQRT2;
93      if(this->paperHeight+2*Plot::psVoffset > Plot::a4height){
94        this->paperHeight = Plot::a4height - 2*Plot::psVoffset;
95        this->paperWidth = this->paperHeight / M_SQRT2;
96      }
97      this->identifier = mycpgopen(pgDestination);
98      if(this->identifier>0) cpgpap(this->paperWidth, this->paperHeight/this->paperWidth);
99      // make paper size to fit on A4.
100      return this->identifier;
101    }
102    //----------------------------------------------------------
103    void SpectralPlot::calcCoords()
104    {
105      /// @details
106      /// Calculates the boundaries for the various boxes, in inches measured
107      ///  from the lower left corner.
108      /// Based on the fact that there are numOnPage spectra shown on each
109      ///  page, going down the page in increasing number (given by
110      ///  SpectralPlot::spectraCount).
111
112      int posOnPage = (this->numOnPage -
113                       (this->spectraCount%this->numOnPage))
114        %this->numOnPage;
115      this->mainCoords[0] = Plot::spMainX1/inchToCm;
116      this->mainCoords[1] = Plot::spMainX2/inchToCm;
117      this->zoomCoords[0] = Plot::spZoomX1/inchToCm;
118      this->zoomCoords[1] = Plot::spZoomX2/inchToCm;
119      this->mainCoords[2] = this->zoomCoords[2] = this->mapCoords[2] =
120        posOnPage*paperHeight/float(this->numOnPage) + Plot::spMainY1/inchToCm;
121      this->mainCoords[3] = this->zoomCoords[3] = this->mapCoords[3] =
122        posOnPage*paperHeight/float(this->numOnPage) + Plot::spMainY2/inchToCm;
123      this->mapCoords[0]  = Plot::spMapX1/inchToCm;
124      this->mapCoords[1]  = this->mapCoords[0] + (this->mapCoords[3]-this->mapCoords[2]);
125    }
126    //----------------------------------------------------------
127    void SpectralPlot::gotoHeader(std::string xlabel)
128    {
129      /// @details
130      /// Calls calcCoords, to calculate correct coordinates for this spectrum.
131      /// Defines the region for the header information, making it centred
132      ///  on the page.
133      /// Also writes the velocity (x axis) label, given by the string argument.
134      /// \param xlabel Label to go on the velocity/spectral axis.
135
136      if(spectraCount%numOnPage==0) cpgpage();
137      spectraCount++;
138      this->calcCoords();
139      cpgvsiz(0., this->paperWidth, this->mainCoords[2], this->mainCoords[3]); 
140      cpgsch(Plot::spLabelSize);
141      cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
142    }
143    //----------------------------------------------------------
144    void SpectralPlot::gotoMainSpectrum(float x1, float x2, float y1, float y2, std::string ylabel)
145    {
146      /// @details
147      ///  Defines the region for the main spectrum.
148      ///  Draws the box, with tick marks, and
149      ///   writes the flux (y axis) label, given by the string argument.
150      /// \param x1 Minimum X-coordinate of box.
151      /// \param x2 Maximum X-coordinate of box.
152      /// \param y1 Minimum Y-coordinate of box.
153      /// \param y2 Maximum Y-coordinate of box.
154      /// \param ylabel Label for the flux (Y) axis.
155
156      cpgvsiz(this->mainCoords[0],this->mainCoords[1],
157              this->mainCoords[2],this->mainCoords[3]);
158      cpgsch(Plot::spIndexSize);
159      cpgswin(x1,x2,y1,y2);
160      cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
161      cpgsch(Plot::spLabelSize);
162      cpgmtxt("l",Plot::spYlabelOffset,0.5,0.5,ylabel.c_str());
163    }
164    //----------------------------------------------------------
165    void SpectralPlot::gotoZoomSpectrum(float x1, float x2, float y1, float y2)
166    {
167      /// @details
168      ///   Defines the region for the zoomed-in part of the spectrum.
169      ///   Draws the box, with special tick marks on the bottom axis.
170      /// \param x1 Minimum X-coordinate of box.
171      /// \param x2 Maximum X-coordinate of box.
172      /// \param y1 Minimum Y-coordinate of box.
173      /// \param y2 Maximum Y-coordinate of box.
174
175      cpgvsiz(this->zoomCoords[0],this->zoomCoords[1],
176              this->zoomCoords[2],this->zoomCoords[3]);
177      cpgsch(Plot::spIndexSize);
178      cpgswin(x1,x2,y1,y2);
179      cpgbox("bc",0.,0,"bcstn1v",0.,0);
180      float lengthL,lengthR,disp,tickpt,step;
181      stringstream label;
182      for(int i=1;i<10;i++){
183        tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
184        switch(i)
185          {
186          case 2:
187          case 8:
188            lengthL = lengthR = 0.5;
189            disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
190            label.str("");
191            label << tickpt;
192            // do a labelled tick mark
193            cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,
194                    disp, 0., label.str().c_str());
195            break;
196          default:
197            label.str("");
198            lengthL = 0.25;
199            lengthR = 0.;
200            disp = 0.;  // not used in this case, but set it anyway.
201            break;
202          }
203        // first the bottom axis, just the ticks
204        if(fabs(tickpt)<(x2-x1)/1.e4) step = 2.*(x2-x1);
205        else step = tickpt;
206        cpgaxis("",
207                tickpt-0.001*(x2-x1), y1,
208                tickpt+0.001*(x2-x1), y1,
209                tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
210                step, -1, lengthL,lengthR, 0.5, disp, 0.);
211        //and now the top -- no labels, just tick marks
212        cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
213      }
214    }
215    //----------------------------------------------------------
216    void SpectralPlot::gotoMap()
217    {
218      cpgvsiz(this->mapCoords[0],this->mapCoords[1],
219              this->mapCoords[2],this->mapCoords[3]);
220      cpgsch(Plot::spIndexSize);
221    }
222    //----------------------------------------------------------
223    void SpectralPlot::drawVelRange(float v1, float v2)
224    {
225      /// @details
226      /// Draws two vertical lines at the limits of velocity
227      ///  given by the arguments.
228      /// \param v1 Minimum velocity.
229      /// \param v2 Maximum velocity.
230
231      int ci,ls;
232      float dud,min,max;
233      cpgqwin(&dud,&dud,&min,&max);
234      cpgqci(&ci);
235      cpgqls(&ls);
236      cpgsci(DUCHAMP_OBJECT_OUTLINE_COLOUR);
237      cpgsls(DASHED);
238      cpgmove(v1,min);  cpgdraw(v1,max);
239      cpgmove(v2,min);  cpgdraw(v2,max);
240      cpgsci(ci);
241      cpgsls(ls);
242    }
243    //----------------------------------------------------------
244    void SpectralPlot::drawMWRange(float v1, float v2)
245    {
246      ///  @details
247      /// Draws a box showing the extent of channels masked by the
248      ///  Milky Way parameters
249      /// \param v1 Minimum velocity of the Milky Way range.
250      /// \param v2 Maximum velocity of the Milky Way range.
251
252      int ci,fs;
253      float dud,min,max,height;
254      cpgqwin(&dud,&dud,&min,&max);
255      height = max-min;
256      max += 0.01*height;
257      min -= 0.01*height;
258      cpgqci(&ci);
259      cpgqfs(&fs);
260      setDarkGreen();
261      cpgsci(DUCHAMP_MILKY_WAY_COLOUR);
262      cpgsfs(HATCHED);
263      cpgrect(v1,v2,min,max);
264      cpgsfs(OUTLINE);
265      cpgrect(v1,v2,min,max);
266      cpgsci(ci);
267      cpgsfs(fs);
268    }
269    //----------------------------------------------------------
270    // SpectralPlot functions...
271    //----------------------------------------------------------
272    void  SpectralPlot::firstHeaderLine(std::string line)
273    {
274      cpgsch(Plot::spTitleSize);
275      cpgmtxt("t",Plot::spTitleOffset1*Plot::spLabelSize/Plot::spTitleSize,
276              0.5,0.5,line.c_str());
277    }
278    void  SpectralPlot::secondHeaderLine(std::string line)
279    {
280      cpgsch(Plot::spLabelSize);
281      cpgmtxt("t",Plot::spTitleOffset2,0.5,0.5,line.c_str());
282    }
283    void  SpectralPlot::thirdHeaderLine(std::string line)
284    {
285      cpgsch(Plot::spLabelSize);
286      cpgmtxt("t",Plot::spTitleOffset3,0.5,0.5,line.c_str());
287    }
288    void  SpectralPlot::fourthHeaderLine(std::string line)
289    {
290      cpgsch(Plot::spLabelSize);
291      cpgmtxt("t",Plot::spTitleOffset4,0.5,0.5,line.c_str());
292    }
293    void  SpectralPlot::goToPlot(){cpgslct(this->identifier);}
294
295    //----------------------------------------------------------
296    //----------------------------------------------------------
297    // ImagePlot functions
298    //----------------------------------------------------------
299
300    ImagePlot::ImagePlot(){
301      this->paperWidth = 7.5;
302      this->maxPaperHeight = 10.;
303      this->marginWidth = 0.8;
304      this->wedgeWidth = 0.7;
305    }
306
307    ImagePlot::~ImagePlot(){}
308
309    ImagePlot::ImagePlot(const ImagePlot& p)
310    {
311      operator=(p);
312    }
313
314    ImagePlot& ImagePlot::operator=(const ImagePlot& p)
315    {
316      if(this==&p) return *this;
317      this->paperWidth = p.paperWidth;   
318      this->maxPaperHeight = p.maxPaperHeight;   
319      this->marginWidth = p.marginWidth;   
320      this->wedgeWidth = p.wedgeWidth;
321      this->imageRatio = p.imageRatio;
322      this->aspectRatio = p.aspectRatio;
323      this->xdim = p.xdim;
324      this->ydim = p.ydim;
325      this->identifier = p.identifier;   
326      return *this;
327    }
328
329    //----------------------------------------------------------
330
331    int ImagePlot::setUpPlot(std::string pgDestination, float x, float y)
332    {
333      /// @details
334      ///  Opens a pgplot device and scales it to the correct shape.
335      ///  In doing so, the dimensions for the image are set, and the required
336      ///   aspect ratios of the image and of the plot are calculated.
337      ///  If the resulting image is going to be tall enough to exceed the
338      ///   maximum height (given the default width), then scale everything
339      ///   down by enough to make the height equal to maxPaperHeight.
340      /// \param pgDestination  The string indicating the PGPLOT device to be
341      ///   written to.
342      /// \param x The length of the X-axis.
343      /// \param y The length of the Y-axis.
344      /// \return The value returned by mycpgopen: if <= 0, then an error
345      ///  has occurred.
346
347      this->xdim = x;
348      this->ydim = y;
349      this->imageRatio= this->ydim / this->xdim;
350      this->aspectRatio =  (this->imageRatio*this->imageWidth() + 2*this->marginWidth)
351        / this->paperWidth;
352      float correction;
353      if((this->imageRatio*this->imageWidth() + 2*this->marginWidth) >
354         this->maxPaperHeight){
355        correction = this->maxPaperHeight /
356          (this->imageRatio*this->imageWidth()+2*this->marginWidth);
357        this->paperWidth *= correction;
358        this->marginWidth *= correction;
359        this->wedgeWidth *= correction;
360      }
361      this->identifier = mycpgopen(pgDestination);
362      if(this->identifier>0) cpgpap(this->paperWidth, this->aspectRatio);
363      return this->identifier;
364    }
365    //----------------------------------------------------------
366    void ImagePlot::drawMapBox(float x1, float x2, float y1, float y2,
367                               std::string xlabel, std::string ylabel)
368    {
369      /// @details
370      ///  Defines the region that the box containing the map is to go in,
371      ///  and draws the box with limits given by the arguments.
372      ///  Also writes labels on both X- and Y-axes.
373      /// \param x1 Minimum X-axis value.
374      /// \param x2 Maximum X-axis value.
375      /// \param y1 Minimum Y-axis value.
376      /// \param y2 Maximum Y-axis value.
377      /// \param xlabel The label to be put on the X-axis.
378      /// \param ylabel The label to be put on the Y-axis.
379
380      cpgvsiz(this->marginWidth, this->marginWidth + this->imageWidth(),
381              this->marginWidth, this->marginWidth + (this->imageWidth()*this->imageRatio) );
382      cpgslw(2);
383      cpgswin(x1,x2,y1,y2);
384      cpgbox("bcst",0.,0,"bcst",0.,0);
385      cpgslw(1);
386      cpgbox("bcnst",0.,0,"bcnst",0.,0);
387      cpglab(xlabel.c_str(), ylabel.c_str(), "");
388    }
389    //----------------------------------------------------------
390   
391    void ImagePlot::makeTitle(std::string title)
392    {
393      /// @details
394      ///   Writes the title for the plot, making it centred for the entire
395      ///    plot and not just the map.
396      ///  \param title String with title for plot.
397
398      cpgvstd();
399      cpgmtxt("t", Plot::imTitleOffset, 0.5, 0.5, title.c_str());
400    }
401
402    void  ImagePlot::goToPlot(){cpgslct(this->identifier);}
403
404    float ImagePlot::imageWidth(){
405      return this->paperWidth - 2*this->marginWidth - this->wedgeWidth;
406    }
407
408    float ImagePlot::cmToCoord(float cm){
409      /** \param cm Distance to be converted.*/
410      return (cm/Plot::inchToCm) * this->ydim / (this->imageWidth()*this->imageRatio);
411    }
412
413
414    //----------------------------------------------------------
415    //----------------------------------------------------------
416    // CutoutPlot functions
417    //----------------------------------------------------------
418    //----------------------------------------------------------
419
420    CutoutPlot::CutoutPlot(){
421      this->paperWidth=a4width/inchToCm - 2*psHoffset;
422      this->sourceCount=0;
423      this->numOnPage = 7;
424    }
425
426    CutoutPlot::~CutoutPlot(){}
427
428    CutoutPlot::CutoutPlot(const CutoutPlot& p)
429    {
430      operator=(p);
431    }
432
433    CutoutPlot& CutoutPlot::operator=(const CutoutPlot& p)
434    {
435      if(this==&p) return *this;
436      this->numOnPage = p.numOnPage;
437      this->sourceCount = p.sourceCount; 
438      for(int i=0;i<4;i++) this->mainCoords[i] = p.mainCoords[i];
439      for(int i=0;i<4;i++) this->mapCoords[i] = p.mapCoords[i];
440      this->paperWidth = p.paperWidth;   
441      this->paperHeight = p.paperHeight;   
442      this->identifier = p.identifier;   
443      return *this;
444    }
445
446    //----------------------------------------------------------
447    int CutoutPlot::setUpPlot(std::string pgDestination)
448    {
449      ///  @details
450      /// Opens the designated pgplot device.  Scales the paper so that
451      /// it fits on an A4 sheet (using known values of the default
452      /// pgplot offsets). 
453      ///
454      /// \param pgDestination The std::string indicating the PGPLOT device to
455      /// be written to.
456      ///
457      /// \return The value returned by mycpgopen. If <= 0, then an error
458      /// has occurred.
459
460      this->paperHeight = this->paperWidth*M_SQRT2;
461      if(this->paperHeight+2*Plot::psVoffset > Plot::a4height){
462        this->paperHeight = Plot::a4height - 2*Plot::psVoffset;
463        this->paperWidth = this->paperHeight / M_SQRT2;
464      }
465      this->identifier = mycpgopen(pgDestination);
466      if(this->identifier>0) cpgpap(this->paperWidth, this->paperHeight/this->paperWidth);
467      // make paper size to fit on A4.
468      return this->identifier;
469    }
470    //----------------------------------------------------------
471    void CutoutPlot::calcCoords()
472    {
473      /// @details
474      /// Calculates the boundaries for the various boxes, in inches measured
475      ///  from the lower left corner.
476      /// Based on the fact that there are numOnPage spectra shown on each
477      ///  page, going down the page in increasing number (given by
478      ///  CutoutPlot::spectraCount).
479
480      int posOnPage = (this->numOnPage -
481                       (this->sourceCount%this->numOnPage))
482        %this->numOnPage;
483      this->mainCoords[0] = Plot::cuMainX1/inchToCm;
484      this->mainCoords[1] = Plot::cuMainX2/inchToCm;
485      this->mainCoords[2] = this->mapCoords[2] =
486        posOnPage*paperHeight/float(this->numOnPage) + Plot::cuMainY1/inchToCm;
487      this->mainCoords[3] = this->mapCoords[3] =
488        posOnPage*paperHeight/float(this->numOnPage) + Plot::cuMainY2/inchToCm;
489      this->mapCoords[0]  = Plot::cuMapX1/inchToCm;
490      this->mapCoords[1]  = this->mapCoords[0] + (this->mapCoords[3]-this->mapCoords[2]);
491    }
492    //----------------------------------------------------------
493    void CutoutPlot::gotoHeader()
494    {
495      ///  @details
496      /// Calls calcCoords, to calculate correct coordinates for this spectrum.
497      /// Defines the region for the header information, making it centred
498      ///  on the page.
499      /// Also writes the velocity (x axis) label, given by the string argument.
500      /// \param xlabel Label to go on the velocity/spectral axis.
501
502      if(sourceCount%numOnPage==0) cpgpage();
503      sourceCount++;
504      this->calcCoords();
505      //     cpgvsiz(0., this->paperWidth, this->mainCoords[2], this->mainCoords[3]); 
506      cpgvsiz(this->mainCoords[0], this->mainCoords[1],
507              this->mainCoords[2], this->mainCoords[3]); 
508      cpgsch(Plot::spLabelSize);
509      //   cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
510      cpgswin(0.,1.,0.,1.);
511      //    cpgbox("bc",0,0,"bc",0,0);
512    }
513    //----------------------------------------------------------
514
515    void CutoutPlot::gotoMap(){
516      cpgvsiz(this->mapCoords[0],this->mapCoords[1],
517              this->mapCoords[2],this->mapCoords[3]);
518      cpgsch(Plot::spIndexSize);
519    }
520    //----------------------------------------------------------
521    // CutoutPlot functions...
522    //----------------------------------------------------------
523    void  CutoutPlot::firstHeaderLine(std::string line)
524    {
525      cpgsch(Plot::spTitleSize);
526      //     cpgmtxt("t",Plot::spTitleOffset1*Plot::spLabelSize/Plot::spTitleSize,
527      //            0.5,0.5,line.c_str());
528      cpgptxt(0.5,0.8,0.,0.5,line.c_str());
529    }
530    void  CutoutPlot::secondHeaderLine(std::string line)
531    {
532      cpgsch(Plot::spLabelSize);
533      //    cpgmtxt("t",Plot::spTitleOffset2,0.5,0.5,line.c_str());
534      cpgptxt(0.5,0.6,0.,0.5,line.c_str());
535    }
536    void  CutoutPlot::thirdHeaderLine(std::string line)
537    {
538      cpgsch(Plot::spLabelSize);
539      //    cpgmtxt("t",Plot::spTitleOffset3,0.5,0.5,line.c_str());
540      cpgptxt(0.5,0.4,0.,0.5,line.c_str());
541    }
542    void  CutoutPlot::fourthHeaderLine(std::string line)
543    {
544      cpgsch(Plot::spLabelSize);
545      //    cpgmtxt("t",Plot::spTitleOffset4,0.5,0.5,line.c_str());
546      cpgptxt(0.5,0.2,0.,0.5,line.c_str());
547    }
548    void  CutoutPlot::goToPlot(){cpgslct(this->identifier);}
549
550  }
551
552}
Note: See TracBrowser for help on using the repository browser.