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

Last change on this file since 987 was 987, checked in by MatthewWhiting, 12 years ago

Enabling the plotting of the thresholds for the regular spectral output. This makes it much more clear how robust the detection is. This is only done for the peak flux spectrum - if spectralMethod = sum it is not plotted.

File size: 26.7 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/fitsHeader.hh>
35#include <duchamp/duchamp.hh>
36#include <duchamp/Utils/mycpgplot.hh>
37#include <duchamp/Utils/Statistics.hh>
38#include <duchamp/Cubes/plots.hh>
39
40using std::stringstream;
41using namespace mycpgplot;
42
43namespace duchamp
44{
45
46  namespace Plot
47  {
48
49    //----------------------------------------------------------
50    // SpectralPlot functions
51    //----------------------------------------------------------
52
53    SpectralPlot::SpectralPlot(){
54      this->paperWidth=a4width/inchToCm - 2*psHoffset;
55      this->aspectRatio = M_SQRT2;
56      this->spectraCount=0;
57      this->numOnPage = 5;
58    }
59
60    SpectralPlot::~SpectralPlot(){}
61
62    SpectralPlot::SpectralPlot(const SpectralPlot& p)
63    {
64      operator=(p);
65    }
66
67    SpectralPlot& SpectralPlot::operator=(const SpectralPlot& p)
68    {
69      if(this==&p) return *this;
70      this->numOnPage = p.numOnPage;
71      this->spectraCount = p.spectraCount; 
72      for(int i=0;i<4;i++) this->mainCoords[i] = p.mainCoords[i];
73      for(int i=0;i<4;i++) this->zoomCoords[i] = p.zoomCoords[i];
74      for(int i=0;i<4;i++) this->mapCoords[i] = p.mapCoords[i];
75      this->paperWidth = p.paperWidth;   
76      this->paperHeight = p.paperHeight;   
77      this->aspectRatio = p.aspectRatio;
78      this->identifier = p.identifier;   
79      return *this;
80    }
81
82    //----------------------------------------------------------
83    int SpectralPlot::setUpPlot(std::string pgDestination)
84    {
85      ///  @details
86      /// Opens the designated pgplot device.  Scales the paper so that
87      /// it fits on an A4 sheet (using known values of the default
88      /// pgplot offsets). 
89      ///
90      /// \param pgDestination The std::string indicating the PGPLOT device to
91      /// be written to.
92      ///
93      /// \return The value returned by mycpgopen. If <= 0, then an error
94      /// has occurred.
95
96      this->paperHeight = this->paperWidth*this->aspectRatio;
97      if(this->paperHeight+2*Plot::psVoffset > Plot::a4height){
98        this->paperHeight = Plot::a4height - 2*Plot::psVoffset;
99        this->paperWidth = this->paperHeight / this->aspectRatio;
100      }
101      this->identifier = mycpgopen(pgDestination);
102      if(this->identifier>0) cpgpap(this->paperWidth, this->aspectRatio);
103      // make paper size to fit on A4.
104      return this->identifier;
105    }
106    //----------------------------------------------------------
107    void SpectralPlot::close()
108    {
109      cpgclos();
110    }
111    //----------------------------------------------------------
112    void SpectralPlot::calcCoords()
113    {
114      /// @details
115      /// Calculates the boundaries for the various boxes, in inches measured
116      ///  from the lower left corner.
117      /// Based on the fact that there are numOnPage spectra shown on each
118      ///  page, going down the page in increasing number (given by
119      ///  SpectralPlot::spectraCount).
120
121      int posOnPage = (this->numOnPage -
122                       (this->spectraCount%this->numOnPage))
123        %this->numOnPage;
124      this->mainCoords[0] = Plot::spMainX1/inchToCm;
125      this->mainCoords[1] = Plot::spMainX2/inchToCm;
126      this->zoomCoords[0] = Plot::spZoomX1/inchToCm;
127      this->zoomCoords[1] = Plot::spZoomX2/inchToCm;
128      this->mainCoords[2] = this->zoomCoords[2] = this->mapCoords[2] =
129        posOnPage*paperHeight/float(this->numOnPage) + Plot::spMainY1/inchToCm;
130      this->mainCoords[3] = this->zoomCoords[3] = this->mapCoords[3] =
131        posOnPage*paperHeight/float(this->numOnPage) + Plot::spMainY2/inchToCm;
132      this->mapCoords[0]  = Plot::spMapX1/inchToCm;
133      this->mapCoords[1]  = this->mapCoords[0] + (this->mapCoords[3]-this->mapCoords[2]);
134    }
135    //----------------------------------------------------------
136    void SpectralPlot::gotoHeader(std::string xlabel)
137    {
138      /// @details
139      /// Calls calcCoords, to calculate correct coordinates for this spectrum.
140      /// Defines the region for the header information, making it centred
141      ///  on the page.
142      /// Also writes the velocity (x axis) label, given by the string argument.
143      /// \param xlabel Label to go on the velocity/spectral axis.
144
145      if(spectraCount%numOnPage==0) cpgpage();
146      spectraCount++;
147      this->calcCoords();
148      cpgvsiz(0., this->paperWidth, this->mainCoords[2], this->mainCoords[3]); 
149      cpgsch(Plot::spLabelSize);
150      cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
151    }
152    //----------------------------------------------------------
153    void SpectralPlot::gotoMainSpectrum(float x1, float x2, float y1, float y2, std::string ylabel)
154    {
155      /// @details
156      ///  Defines the region for the main spectrum.
157      ///  Draws the box, with tick marks, and
158      ///   writes the flux (y axis) label, given by the string argument.
159      /// \param x1 Minimum X-coordinate of box.
160      /// \param x2 Maximum X-coordinate of box.
161      /// \param y1 Minimum Y-coordinate of box.
162      /// \param y2 Maximum Y-coordinate of box.
163      /// \param ylabel Label for the flux (Y) axis.
164
165      cpgvsiz(this->mainCoords[0],this->mainCoords[1],
166              this->mainCoords[2],this->mainCoords[3]);
167      cpgsch(Plot::spIndexSize);
168      cpgswin(x1,x2,y1,y2);
169      cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
170      cpgsch(Plot::spLabelSize);
171      cpgmtxt("l",Plot::spYlabelOffset,0.5,0.5,ylabel.c_str());
172    }
173    //----------------------------------------------------------
174    void SpectralPlot::gotoZoomSpectrum(float x1, float x2, float y1, float y2)
175    {
176      /// @details
177      ///   Defines the region for the zoomed-in part of the spectrum.
178      ///   Draws the box, with special tick marks on the bottom axis.
179      /// \param x1 Minimum X-coordinate of box.
180      /// \param x2 Maximum X-coordinate of box.
181      /// \param y1 Minimum Y-coordinate of box.
182      /// \param y2 Maximum Y-coordinate of box.
183
184      cpgvsiz(this->zoomCoords[0],this->zoomCoords[1],
185              this->zoomCoords[2],this->zoomCoords[3]);
186      cpgsch(Plot::spIndexSize);
187      cpgswin(x1,x2,y1,y2);
188      cpgbox("bc",0.,0,"bcstn1v",0.,0);
189      float lengthL,lengthR,disp,tickpt,step;
190      stringstream label;
191      for(int i=1;i<10;i++){
192        tickpt = x1+(x2-x1)*float(i)/10.;  // spectral coord of the tick
193        switch(i)
194          {
195          case 2:
196          case 8:
197            lengthL = lengthR = 0.5;
198            disp = 0.3 + float(i-2)/6.; // i==2 --> disp=0.3, i==8 --> disp=1.3
199            label.str("");
200            label << tickpt;
201            // do a labelled tick mark
202            cpgtick(x1,y1,x2,y1,float(i)/10.,lengthL,lengthR,
203                    disp, 0., label.str().c_str());
204            break;
205          default:
206            label.str("");
207            lengthL = 0.25;
208            lengthR = 0.;
209            disp = 0.;  // not used in this case, but set it anyway.
210            break;
211          }
212        // first the bottom axis, just the ticks
213        if(fabs(tickpt)<(x2-x1)/1.e4) step = 2.*(x2-x1);
214        else step = tickpt;
215        cpgaxis("",
216                tickpt-0.001*(x2-x1), y1,
217                tickpt+0.001*(x2-x1), y1,
218                tickpt-0.001*(x2-x1), tickpt+0.001*(x2-x1),
219                step, -1, lengthL,lengthR, 0.5, disp, 0.);
220        //and now the top -- no labels, just tick marks
221        cpgtick(x1,y2,x2,y2,float(i)/10.,lengthL,lengthR,0.,0.,"");
222      }
223    }
224    //----------------------------------------------------------
225    void SpectralPlot::gotoMap()
226    {
227      cpgvsiz(this->mapCoords[0],this->mapCoords[1],
228              this->mapCoords[2],this->mapCoords[3]);
229      cpgsch(Plot::spIndexSize);
230    }
231    //----------------------------------------------------------
232    void SpectralPlot::drawVelRange(float v1, float v2)
233    {
234      /// @details
235      /// Draws two vertical lines at the limits of velocity
236      ///  given by the arguments.
237      /// \param v1 Minimum velocity.
238      /// \param v2 Maximum velocity.
239
240      int ci,ls;
241      float dud,min,max;
242      cpgqwin(&dud,&dud,&min,&max);
243      cpgqci(&ci);
244      cpgqls(&ls);
245      cpgsci(DUCHAMP_OBJECT_OUTLINE_COLOUR);
246      cpgsls(DASHED);
247      cpgmove(v1,min);  cpgdraw(v1,max);
248      cpgmove(v2,min);  cpgdraw(v2,max);
249      cpgsci(ci);
250      cpgsls(ls);
251    }
252    //----------------------------------------------------------
253    void SpectralPlot::drawMWRange(float v1, float v2)
254    {
255      ///  @details
256      /// Draws a box showing the extent of channels masked by the
257      ///  Milky Way parameters
258      /// \param v1 Minimum velocity of the Milky Way range.
259      /// \param v2 Maximum velocity of the Milky Way range.
260
261      int ci,fs;
262      float dud,min,max,height;
263      cpgqwin(&dud,&dud,&min,&max);
264      height = max-min;
265      max += 0.01*height;
266      min -= 0.01*height;
267      cpgqci(&ci);
268      cpgqfs(&fs);
269      setDarkGreen();
270      cpgsci(DUCHAMP_MILKY_WAY_COLOUR);
271      cpgsfs(HATCHED);
272      cpgrect(v1,v2,min,max);
273      cpgsfs(OUTLINE);
274      cpgrect(v1,v2,min,max);
275      cpgsci(ci);
276      cpgsfs(fs);
277    }
278    //----------------------------------------------------------
279    void SpectralPlot::drawThresholds(Param &par, Statistics::StatsContainer<float> &stats)
280    {
281
282      float dud,vmin,vmax;
283      cpgqwin(&vmin,&vmax,&dud,&dud);
284        cpgsci(RED);
285        cpgsls(DASHED);
286        float thresh = stats.getThreshold();
287        if(par.getFlagNegative()) thresh *= -1.;
288        cpgmove(vmin,thresh);
289        cpgdraw(vmax,thresh);
290        if(par.getFlagGrowth()){
291          if(par.getFlagUserGrowthThreshold()) thresh= par.getGrowthThreshold();
292          else thresh= stats.snrToValue(par.getGrowthCut());
293          if(par.getFlagNegative()) thresh *= -1.;     
294          cpgsls(DOTTED);
295          cpgmove(vmin,thresh);
296          cpgdraw(vmax,thresh);
297        }
298        cpgsci(FOREGND);
299        cpgsls(SOLID);
300
301    }
302    //----------------------------------------------------------
303    // SpectralPlot functions...
304    //----------------------------------------------------------
305    void  SpectralPlot::firstHeaderLine(std::string line)
306    {
307      cpgsch(Plot::spTitleSize);
308      cpgmtxt("t",Plot::spTitleOffset1*Plot::spLabelSize/Plot::spTitleSize,
309              0.5,0.5,line.c_str());
310    }
311    void  SpectralPlot::secondHeaderLine(std::string line)
312    {
313      cpgsch(Plot::spLabelSize);
314      cpgmtxt("t",Plot::spTitleOffset2,0.5,0.5,line.c_str());
315    }
316    void  SpectralPlot::thirdHeaderLine(std::string line)
317    {
318      cpgsch(Plot::spLabelSize);
319      cpgmtxt("t",Plot::spTitleOffset3,0.5,0.5,line.c_str());
320    }
321    void  SpectralPlot::fourthHeaderLine(std::string line)
322    {
323      cpgsch(Plot::spLabelSize);
324      cpgmtxt("t",Plot::spTitleOffset4,0.5,0.5,line.c_str());
325    }
326    void  SpectralPlot::goToPlot(){cpgslct(this->identifier);}
327
328    //----------------------------------------------------------
329    // SimpleSpectralPlot functions
330    //----------------------------------------------------------
331
332    SimpleSpectralPlot::SimpleSpectralPlot(){
333      this->paperWidth=a4width/inchToCm - 2*psHoffset;
334      this->aspectRatio = M_SQRT2/5.;
335    }
336
337    SimpleSpectralPlot::~SimpleSpectralPlot(){}
338
339    SimpleSpectralPlot::SimpleSpectralPlot(const SimpleSpectralPlot& p)
340    {
341      operator=(p);
342    }
343
344    SimpleSpectralPlot& SimpleSpectralPlot::operator=(const SimpleSpectralPlot& p)
345    {
346      if(this==&p) return *this;
347      for(int i=0;i<4;i++) this->mainCoords[i] = p.mainCoords[i];
348      this->paperWidth = p.paperWidth;   
349      this->paperHeight = p.paperHeight;   
350      this->aspectRatio = p.aspectRatio;
351      this->identifier = p.identifier;   
352      return *this;
353    }
354
355    //----------------------------------------------------------
356    int SimpleSpectralPlot::setUpPlot(std::string pgDestination)
357    {
358      ///  @details
359      /// Opens the designated pgplot device.  Scales the paper so that
360      /// it fits on an A4 sheet (using known values of the default
361      /// pgplot offsets). 
362      ///
363      /// \param pgDestination The std::string indicating the PGPLOT device to
364      /// be written to.
365      ///
366      /// \return The value returned by mycpgopen. If <= 0, then an error
367      /// has occurred.
368
369      if(pgDestination == "/xs") this->paperWidth=12.;
370
371      this->paperHeight = this->paperWidth*this->aspectRatio;
372      this->identifier = mycpgopen(pgDestination);
373      if(this->identifier>0) cpgpap(this->paperWidth, this->aspectRatio);
374      // make paper size to fit on A4.
375      float scaling = this->paperWidth*inchToCm / a4width;
376      this->mainCoords[0] = Plot::spMainX1/inchToCm * scaling;
377      this->mainCoords[1] = (Plot::spMapX1+Plot::spMainY2-Plot::spMainY1)/inchToCm * scaling;
378      this->mainCoords[2] = Plot::spMainY1/inchToCm * scaling;
379      this->mainCoords[3] = Plot::spMainY2/inchToCm * scaling;
380      return this->identifier;
381    }
382    //----------------------------------------------------------
383    void SimpleSpectralPlot::close()
384    {
385      cpgclos();
386    }
387    void SimpleSpectralPlot::label(std::string xlabel,std::string ylabel, std::string title)
388    {
389      /// @details
390      /// Calls calcCoords, to calculate correct coordinates for this spectrum.
391      /// Defines the region for the header information, making it centred
392      ///  on the page.
393      /// Also writes the velocity (x axis) label, given by the string argument.
394      /// \param xlabel Label to go on the velocity/spectral axis.
395
396      cpgvsiz(this->mainCoords[0],this->mainCoords[1],this->mainCoords[2],this->mainCoords[3]);
397      cpgsch(2.);
398      cpgmtxt("B",3.,0.5,0.5,xlabel.c_str());
399      cpgmtxt("L",4.,0.5,0.5,ylabel.c_str());
400      cpgmtxt("T",2.,0.5,0.5,title.c_str());
401    }
402    //----------------------------------------------------------
403    void SimpleSpectralPlot::gotoMainSpectrum(float x1, float x2, float y1, float y2)
404    {
405      /// @details
406      ///  Defines the region for the main spectrum.
407      ///  Draws the box, with tick marks, and
408      ///   writes the flux (y axis) label, given by the string argument.
409      /// \param x1 Minimum X-coordinate of box.
410      /// \param x2 Maximum X-coordinate of box.
411      /// \param y1 Minimum Y-coordinate of box.
412      /// \param y2 Maximum Y-coordinate of box.
413      /// \param ylabel Label for the flux (Y) axis.
414
415      cpgvsiz(this->mainCoords[0],this->mainCoords[1],this->mainCoords[2],this->mainCoords[3]);
416      cpgsch(2.);
417      cpgswin(x1,x2,y1,y2);
418      cpgbox("1bcnst",0.,0,"bcnst1v",0.,0);
419    }
420    //----------------------------------------------------------
421    void SimpleSpectralPlot::drawDetectPixel(int z, FitsHeader &head)
422    {
423      float v1,v2;
424      double zero=0.;
425      if(head.isWCS()){
426        double zpt=double(z-0.5);
427        v1=head.pixToVel(zero,zero,zpt);
428        zpt=double(z+0.5);
429        v2=head.pixToVel(zero,zero,zpt);
430      }
431      else{
432        v1=float(z-0.5);
433        v2=float(z+0.5);
434      }
435      float x1,x2,y1,y2;
436      cpgqwin(&x1,&x2,&y1,&y2);
437      float y=y2-0.05*(y2-y1);
438      int lw;
439      cpgqlw(&lw);
440      cpgslw(3);
441      cpgmove(v1,y);
442      cpgdraw(v2,y);
443      cpgslw(lw);
444    }
445    //----------------------------------------------------------
446    void SimpleSpectralPlot::drawVelRange(float v1, float v2)
447    {
448      /// @details
449      /// Draws two vertical lines at the limits of velocity
450      ///  given by the arguments.
451      /// \param v1 Minimum velocity.
452      /// \param v2 Maximum velocity.
453
454      int ci,ls;
455      float dud,min,max;
456      cpgqwin(&dud,&dud,&min,&max);
457      cpgqci(&ci);
458      cpgqls(&ls);
459      cpgsci(DUCHAMP_OBJECT_OUTLINE_COLOUR);
460      cpgsls(DASHED);
461      cpgmove(v1,min);  cpgdraw(v1,max);
462      cpgmove(v2,min);  cpgdraw(v2,max);
463      cpgsci(ci);
464      cpgsls(ls);
465    }
466    //----------------------------------------------------------
467    void SimpleSpectralPlot::drawMWRange(float v1, float v2)
468    {
469      ///  @details
470      /// Draws a box showing the extent of channels masked by the
471      ///  Milky Way parameters
472      /// \param v1 Minimum velocity of the Milky Way range.
473      /// \param v2 Maximum velocity of the Milky Way range.
474
475      int ci,fs;
476      float dud,min,max,height;
477      cpgqwin(&dud,&dud,&min,&max);
478      height = max-min;
479      max += 0.01*height;
480      min -= 0.01*height;
481      cpgqci(&ci);
482      cpgqfs(&fs);
483      setDarkGreen();
484      cpgsci(DUCHAMP_MILKY_WAY_COLOUR);
485      cpgsfs(HATCHED);
486      cpgrect(v1,v2,min,max);
487      cpgsfs(OUTLINE);
488      cpgrect(v1,v2,min,max);
489      cpgsci(ci);
490      cpgsfs(fs);
491    }
492
493
494    //----------------------------------------------------------
495    //----------------------------------------------------------
496    // ImagePlot functions
497    //----------------------------------------------------------
498
499    ImagePlot::ImagePlot(){
500      this->paperWidth = 7.5;
501      this->maxPaperHeight = 10.;
502      this->marginWidth = 0.8;
503      this->wedgeWidth = 0.7;
504    }
505
506    ImagePlot::~ImagePlot(){}
507
508    ImagePlot::ImagePlot(const ImagePlot& p)
509    {
510      operator=(p);
511    }
512
513    ImagePlot& ImagePlot::operator=(const ImagePlot& p)
514    {
515      if(this==&p) return *this;
516      this->paperWidth = p.paperWidth;   
517      this->maxPaperHeight = p.maxPaperHeight;   
518      this->marginWidth = p.marginWidth;   
519      this->wedgeWidth = p.wedgeWidth;
520      this->imageRatio = p.imageRatio;
521      this->aspectRatio = p.aspectRatio;
522      this->xdim = p.xdim;
523      this->ydim = p.ydim;
524      this->identifier = p.identifier;   
525      return *this;
526    }
527
528    //----------------------------------------------------------
529
530    int ImagePlot::setUpPlot(std::string pgDestination, float x, float y)
531    {
532      /// @details
533      ///  Opens a pgplot device and scales it to the correct shape.
534      ///  In doing so, the dimensions for the image are set, and the required
535      ///   aspect ratios of the image and of the plot are calculated.
536      ///  If the resulting image is going to be tall enough to exceed the
537      ///   maximum height (given the default width), then scale everything
538      ///   down by enough to make the height equal to maxPaperHeight.
539      /// \param pgDestination  The string indicating the PGPLOT device to be
540      ///   written to.
541      /// \param x The length of the X-axis.
542      /// \param y The length of the Y-axis.
543      /// \return The value returned by mycpgopen: if <= 0, then an error
544      ///  has occurred.
545
546      this->xdim = x;
547      this->ydim = y;
548      this->imageRatio= this->ydim / this->xdim;
549      this->aspectRatio =  (this->imageRatio*this->imageWidth() + 2*this->marginWidth)
550        / this->paperWidth;
551      float correction;
552      if((this->imageRatio*this->imageWidth() + 2*this->marginWidth) >
553         this->maxPaperHeight){
554        correction = this->maxPaperHeight /
555          (this->imageRatio*this->imageWidth()+2*this->marginWidth);
556        this->paperWidth *= correction;
557        this->marginWidth *= correction;
558        this->wedgeWidth *= correction;
559      }
560      this->identifier = mycpgopen(pgDestination);
561      if(this->identifier>0) cpgpap(this->paperWidth, this->aspectRatio);
562      return this->identifier;
563    }
564    //----------------------------------------------------------
565    void ImagePlot::close()
566    {
567      cpgclos();
568    }
569    //----------------------------------------------------------
570    void ImagePlot::drawMapBox(float x1, float x2, float y1, float y2,
571                               std::string xlabel, std::string ylabel)
572    {
573      /// @details
574      ///  Defines the region that the box containing the map is to go in,
575      ///  and draws the box with limits given by the arguments.
576      ///  Also writes labels on both X- and Y-axes.
577      /// \param x1 Minimum X-axis value.
578      /// \param x2 Maximum X-axis value.
579      /// \param y1 Minimum Y-axis value.
580      /// \param y2 Maximum Y-axis value.
581      /// \param xlabel The label to be put on the X-axis.
582      /// \param ylabel The label to be put on the Y-axis.
583
584      cpgvsiz(this->marginWidth, this->marginWidth + this->imageWidth(),
585              this->marginWidth, this->marginWidth + (this->imageWidth()*this->imageRatio) );
586      cpgslw(2);
587      cpgswin(x1,x2,y1,y2);
588      cpgbox("bcst",0.,0,"bcst",0.,0);
589      cpgslw(1);
590      cpgbox("bcnst",0.,0,"bcnst",0.,0);
591      cpglab(xlabel.c_str(), ylabel.c_str(), "");
592    }
593    //----------------------------------------------------------
594   
595    void ImagePlot::makeTitle(std::string title)
596    {
597      /// @details
598      ///   Writes the title for the plot, making it centred for the entire
599      ///    plot and not just the map.
600      ///  \param title String with title for plot.
601
602      cpgvstd();
603      cpgmtxt("t", Plot::imTitleOffset, 0.5, 0.5, title.c_str());
604    }
605
606    void  ImagePlot::goToPlot(){cpgslct(this->identifier);}
607
608    float ImagePlot::imageWidth(){
609      return this->paperWidth - 2*this->marginWidth - this->wedgeWidth;
610    }
611
612    float ImagePlot::cmToCoord(float cm){
613      /** \param cm Distance to be converted.*/
614      return (cm/Plot::inchToCm) * this->ydim / (this->imageWidth()*this->imageRatio);
615    }
616
617
618    //----------------------------------------------------------
619    //----------------------------------------------------------
620    // CutoutPlot functions
621    //----------------------------------------------------------
622    //----------------------------------------------------------
623
624    CutoutPlot::CutoutPlot(){
625      this->paperWidth=a4width/inchToCm - 2*psHoffset;
626      this->sourceCount=0;
627      this->numOnPage = 7;
628    }
629
630    CutoutPlot::~CutoutPlot(){}
631
632    CutoutPlot::CutoutPlot(const CutoutPlot& p)
633    {
634      operator=(p);
635    }
636
637    CutoutPlot& CutoutPlot::operator=(const CutoutPlot& p)
638    {
639      if(this==&p) return *this;
640      this->numOnPage = p.numOnPage;
641      this->sourceCount = p.sourceCount; 
642      for(int i=0;i<4;i++) this->mainCoords[i] = p.mainCoords[i];
643      for(int i=0;i<4;i++) this->mapCoords[i] = p.mapCoords[i];
644      this->paperWidth = p.paperWidth;   
645      this->paperHeight = p.paperHeight;   
646      this->identifier = p.identifier;   
647      return *this;
648    }
649
650    //----------------------------------------------------------
651    int CutoutPlot::setUpPlot(std::string pgDestination)
652    {
653      ///  @details
654      /// Opens the designated pgplot device.  Scales the paper so that
655      /// it fits on an A4 sheet (using known values of the default
656      /// pgplot offsets). 
657      ///
658      /// \param pgDestination The std::string indicating the PGPLOT device to
659      /// be written to.
660      ///
661      /// \return The value returned by mycpgopen. If <= 0, then an error
662      /// has occurred.
663
664      this->paperHeight = this->paperWidth*M_SQRT2;
665      if(this->paperHeight+2*Plot::psVoffset > Plot::a4height){
666        this->paperHeight = Plot::a4height - 2*Plot::psVoffset;
667        this->paperWidth = this->paperHeight / M_SQRT2;
668      }
669      this->identifier = mycpgopen(pgDestination);
670      if(this->identifier>0) cpgpap(this->paperWidth, this->paperHeight/this->paperWidth);
671      // make paper size to fit on A4.
672      return this->identifier;
673    }
674    //----------------------------------------------------------
675    void CutoutPlot::calcCoords()
676    {
677      /// @details
678      /// Calculates the boundaries for the various boxes, in inches measured
679      ///  from the lower left corner.
680      /// Based on the fact that there are numOnPage spectra shown on each
681      ///  page, going down the page in increasing number (given by
682      ///  CutoutPlot::spectraCount).
683
684      int posOnPage = (this->numOnPage -
685                       (this->sourceCount%this->numOnPage))
686        %this->numOnPage;
687      this->mainCoords[0] = Plot::cuMainX1/inchToCm;
688      this->mainCoords[1] = Plot::cuMainX2/inchToCm;
689      this->mainCoords[2] = this->mapCoords[2] =
690        posOnPage*paperHeight/float(this->numOnPage) + Plot::cuMainY1/inchToCm;
691      this->mainCoords[3] = this->mapCoords[3] =
692        posOnPage*paperHeight/float(this->numOnPage) + Plot::cuMainY2/inchToCm;
693      this->mapCoords[0]  = Plot::cuMapX1/inchToCm;
694      this->mapCoords[1]  = this->mapCoords[0] + (this->mapCoords[3]-this->mapCoords[2]);
695    }
696    //----------------------------------------------------------
697    void CutoutPlot::gotoHeader()
698    {
699      ///  @details
700      /// Calls calcCoords, to calculate correct coordinates for this spectrum.
701      /// Defines the region for the header information, making it centred
702      ///  on the page.
703      /// Also writes the velocity (x axis) label, given by the string argument.
704      /// \param xlabel Label to go on the velocity/spectral axis.
705
706      if(sourceCount%numOnPage==0) cpgpage();
707      sourceCount++;
708      this->calcCoords();
709      //     cpgvsiz(0., this->paperWidth, this->mainCoords[2], this->mainCoords[3]); 
710      cpgvsiz(this->mainCoords[0], this->mainCoords[1],
711              this->mainCoords[2], this->mainCoords[3]); 
712      cpgsch(Plot::spLabelSize);
713      //   cpgmtxt("b",Plot::spXlabelOffset,0.5,0.5,xlabel.c_str());
714      cpgswin(0.,1.,0.,1.);
715      //    cpgbox("bc",0,0,"bc",0,0);
716    }
717    //----------------------------------------------------------
718
719    void CutoutPlot::gotoMap(){
720      cpgvsiz(this->mapCoords[0],this->mapCoords[1],
721              this->mapCoords[2],this->mapCoords[3]);
722      cpgsch(Plot::spIndexSize);
723    }
724    //----------------------------------------------------------
725    // CutoutPlot functions...
726    //----------------------------------------------------------
727    void  CutoutPlot::firstHeaderLine(std::string line)
728    {
729      cpgsch(Plot::spTitleSize);
730      //     cpgmtxt("t",Plot::spTitleOffset1*Plot::spLabelSize/Plot::spTitleSize,
731      //            0.5,0.5,line.c_str());
732      cpgptxt(0.5,0.8,0.,0.5,line.c_str());
733    }
734    void  CutoutPlot::secondHeaderLine(std::string line)
735    {
736      cpgsch(Plot::spLabelSize);
737      //    cpgmtxt("t",Plot::spTitleOffset2,0.5,0.5,line.c_str());
738      cpgptxt(0.5,0.6,0.,0.5,line.c_str());
739    }
740    void  CutoutPlot::thirdHeaderLine(std::string line)
741    {
742      cpgsch(Plot::spLabelSize);
743      //    cpgmtxt("t",Plot::spTitleOffset3,0.5,0.5,line.c_str());
744      cpgptxt(0.5,0.4,0.,0.5,line.c_str());
745    }
746    void  CutoutPlot::fourthHeaderLine(std::string line)
747    {
748      cpgsch(Plot::spLabelSize);
749      //    cpgmtxt("t",Plot::spTitleOffset4,0.5,0.5,line.c_str());
750      cpgptxt(0.5,0.2,0.,0.5,line.c_str());
751    }
752    void  CutoutPlot::goToPlot(){cpgslct(this->identifier);}
753
754  }
755
756}
Note: See TracBrowser for help on using the repository browser.