source: tags/release-1.1.4/src/Utils/Section.cc @ 1441

Last change on this file since 1441 was 393, checked in by MatthewWhiting, 17 years ago

Fixed up headers for trunk as well.

File size: 6.5 KB
Line 
1// -----------------------------------------------------------------------
2// Section.cc: Member functions for the Section class, particularly
3//             how to interpret the subsection string.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <string>
30#include <vector>
31#include <iostream>
32#include <sstream>
33#include <duchamp/Utils/Section.hh>
34#include <duchamp/duchamp.hh>
35
36namespace duchamp
37{
38
39  Section::Section()
40  {
41    this->numSections = 0;
42  }
43
44  Section::Section(const Section& s)
45  {
46    operator=(s);
47  }
48  //--------------------------------------------
49 
50  Section& Section::operator= (const Section& s)
51  {
52    if(this == &s) return *this;
53    this->subsection  = s.subsection;
54    this->numSections = s.numSections;
55    this->starts            = s.starts;
56    this->dims        = s.dims;
57    return *this;
58  }
59  //--------------------------------------------
60
61  int Section::parse(std::vector<long> dimAxes)
62  {
63    /**
64     * This function reads the subsection string, and registers the
65     * starting values and lengths for each dimension. The array of axis
66     * dimensions is needed to know how long each axis really is, and
67     * whether we have strayed over the limit or not.
68     *
69     * Note that steps in the subsection string are not dealt with -- a
70     * warning message is written to the screen, and the step values are
71     * removed from the subsection string.
72     *
73     * The function also does basic checks to make sure it is of the
74     * correct format (ie. has square brackets delimiting it) and the
75     * correct number of sections, returning a FAILURE if either of
76     * these checks fail.
77     *
78     * \param dimAxes The array of axis dimensions, of which the
79     *                 Section is a subsection.
80     * \return SUCCESS/FAILURE (from duchamp.hh)
81     */
82
83    std::stringstream errmsg;
84
85    // First Make sure subsection has [ and ] at ends
86    if((this->subsection[0]!='[') ||
87       (this->subsection[this->subsection.size()-1]!=']')){
88      errmsg.str("");
89      errmsg << "Subsection needs to be delimited by square brackets\n"
90             << "You provided: " << this->subsection << std::endl;
91      duchampError("Section parsing",errmsg.str());
92      return FAILURE;
93    }
94
95    this->starts.clear();
96    this->dims.clear();
97 
98    this->numSections=1;
99    for(int i=0;i<this->subsection.size();i++)
100      if(this->subsection[i]==',') this->numSections++;
101
102    if(numSections!=dimAxes.size()){
103      errmsg.str("");
104      errmsg << "Subsection has "<<numSections
105             <<" sections, compared to a cube with "
106             << dimAxes.size() << " axes\n"
107             << "Subsection provided was: " << this->subsection << std::endl;
108      duchampError("Section parsing",errmsg.str());
109      return FAILURE;
110    }
111
112    this->starts.resize(this->numSections);
113    this->dims.resize(this->numSections);
114
115    std::vector<std::string> sections(numSections);
116    // this will hold the section strings for each dimension
117    std::stringstream ss;
118    ss.str(this->subsection);
119    bool removeStep = false;
120    bool doingBorders = false;
121    std::string temp;
122
123    getline(ss,temp,'[');
124    for(int i=0;i<numSections-1;i++){
125      getline(ss,temp,',');
126      sections[i]=temp;
127    }
128    getline(ss,temp,']');
129    sections[numSections-1]=temp;
130
131    for(int str=0;str<numSections;str++){
132      if(sections[str]=="*"){
133        this->starts[str] = 0;
134        this->dims[str]= dimAxes[str];
135      }
136      else{
137        int numColon=0;
138        for(int i=0;i<sections[str].size();i++){
139          if(sections[str][i]==':'){
140            sections[str][i]=' ';
141            numColon++;
142          }
143        }
144        int a,b,c;
145        std::stringstream readString,fixedString;
146        readString.str(sections[str]);
147        switch(numColon){
148        case 1: // usual case
149          readString >> a >> b;
150          this->starts[str] = a-1;
151          this->dims[str] = b-a+1;
152          break;
153        case 0: // borders case -- so many off each border
154          readString >> a;
155          if(a>=dimAxes[str]/2){
156            errmsg.str("");
157            errmsg<< "You requested the subsection " << this->subsection
158                  << " but axis #" << str+1
159                  <<" has zero size, since its dimension is " << dimAxes[str]
160                  <<".\nI'm not going to parse this! Go and fix it.\n";
161            duchampError("Section parsing", errmsg.str());
162            return FAILURE;
163          }
164          this->starts[str] = a;
165          this->dims[str] = dimAxes[str]-2*a;
166          fixedString << this->starts[str]+1 << ":"
167                      << this->getEnd(str)+1;
168          sections[str] = fixedString.str();
169          doingBorders=true;
170          break;
171        case 2: // subsection involves a step
172        default:
173          readString>> a >> b >> c;
174          this->starts[str] = a-1;
175          this->dims[str] = b-a+1;
176          fixedString << a << ":" << b;
177          sections[str] = fixedString.str();
178          removeStep=true;
179          break;
180        }
181
182      }
183    }
184
185    if(removeStep){  // if there was a step present
186      errmsg.str("");
187      errmsg << "The subsection given is " << this->subsection <<".\n"
188             << "Duchamp is currently unable to deal with pixel steps"
189             << " in the subsection.\n"
190             << "These have been ignored, and so the subection used is ";
191    }
192
193    if(removeStep || doingBorders){
194      // rewrite subsection without any step sizes and with correct borders.
195      this->subsection = "[" + sections[0];
196      for(int str=1;str<numSections;str++)
197        this->subsection += ',' + sections[str];
198      this->subsection += "]";
199    }
200
201    if(removeStep){
202      errmsg << this->subsection << std::endl;
203      duchampWarning("Section parsing", errmsg.str());
204    }
205
206    return SUCCESS;
207 
208  }
209
210}
Note: See TracBrowser for help on using the repository browser.