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

Last change on this file since 1441 was 698, checked in by MatthewWhiting, 14 years ago

A bunch of changes aimed at improving the use of OUTCOME to report SUCCESS/FAILURE. When such a value is returned by a function, the returned type is duchamp::OUTCOME.

Also improved the error reporting in saveImage

File size: 7.3 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  OUTCOME Section::parse(long *dimAxes, int size)
62  {
63    std::vector<long> vecDim(size);
64    for(int i=0;i<size;i++) vecDim[i] = dimAxes[i];
65    return this->parse(vecDim);
66  }
67
68  OUTCOME Section::parse(std::vector<int> dimAxes)
69  {
70    std::vector<long> vecDim(dimAxes.size());
71    for(size_t i=0;i<dimAxes.size();i++) vecDim[i] = long(dimAxes[i]);
72    return this->parse(vecDim);
73  }
74
75  OUTCOME Section::parse(std::vector<long> dimAxes)
76  {
77    /// @details
78    /// This function reads the subsection string, and registers the
79    /// starting values and lengths for each dimension. The array of axis
80    /// dimensions is needed to know how long each axis really is, and
81    /// whether we have strayed over the limit or not.
82    ///
83    /// Note that steps in the subsection string are not dealt with -- a
84    /// warning message is written to the screen, and the step values are
85    /// removed from the subsection string.
86    ///
87    /// The function also does basic checks to make sure it is of the
88    /// correct format (ie. has square brackets delimiting it) and the
89    /// correct number of sections, returning a FAILURE if either of
90    /// these checks fail.
91    ///
92    /// \param dimAxes The array of axis dimensions, of which the
93    ///                 Section is a subsection.
94    /// \return SUCCESS/FAILURE (from duchamp.hh)
95
96    std::stringstream errmsg;
97
98    // First Make sure subsection has [ and ] at ends
99    if((this->subsection[0]!='[') ||
100       (this->subsection[this->subsection.size()-1]!=']')){
101      errmsg.str("");
102      errmsg << "Subsection needs to be delimited by square brackets\n"
103             << "You provided: " << this->subsection << std::endl;
104      duchampError("Section parsing",errmsg.str());
105      return FAILURE;
106    }
107
108    this->starts.clear();
109    this->dims.clear();
110 
111    this->numSections=1;
112    for(size_t i=0;i<this->subsection.size();i++)
113      if(this->subsection[i]==',') this->numSections++;
114
115    if(numSections!=dimAxes.size()){
116      errmsg.str("");
117      errmsg << "Subsection has "<<numSections
118             <<" sections, compared to a cube with "
119             << dimAxes.size() << " axes\n"
120             << "Subsection provided was: " << this->subsection << std::endl;
121      duchampError("Section parsing",errmsg.str());
122      return FAILURE;
123    }
124
125    this->starts.resize(this->numSections);
126    this->dims.resize(this->numSections);
127    this->sections.resize(this->numSections);
128
129    std::vector<std::string> tempsections(numSections);
130    // this will hold the section strings for each dimension
131    std::stringstream ss;
132    ss.str(this->subsection);
133    bool removeStep = false;
134    bool doingBorders = false;
135    std::string temp;
136
137    getline(ss,temp,'[');
138    for(size_t i=0;i<numSections-1;i++){
139      getline(ss,temp,',');
140      tempsections[i]=temp;
141    }
142    getline(ss,temp,']');
143    tempsections[numSections-1]=temp;
144
145    for(size_t str=0;str<numSections;str++){
146      if(tempsections[str]=="*"){
147        this->starts[str] = 0;
148        this->dims[str]= dimAxes[str];
149        this->sections[str] = tempsections[str];
150      }
151      else{
152        int numColon=0;
153        for(size_t i=0;i<tempsections[str].size();i++){
154          if(tempsections[str][i]==':'){
155            tempsections[str][i]=' ';
156            numColon++;
157          }
158        }
159        int a,b,c;
160        std::stringstream readString,fixedString;
161        readString.str(tempsections[str]);
162        switch(numColon){
163        case 1: // usual case
164          readString >> a >> b;
165          this->starts[str] = a-1;
166          this->dims[str] = b-a+1;
167          fixedString << a << ":" << b;
168          this->sections[str] = fixedString.str();
169          break;
170        case 0: // borders case -- so many off each border
171          readString >> a;
172          if(a>=dimAxes[str]/2){
173            errmsg.str("");
174            errmsg<< "You requested the subsection " << this->subsection
175                  << " but axis #" << str+1
176                  <<" has zero size, since its dimension is " << dimAxes[str]
177                  <<".\nI'm not going to parse this! Go and fix it.\n";
178            duchampError("Section parsing", errmsg.str());
179            return FAILURE;
180          }
181          this->starts[str] = a;
182          this->dims[str] = dimAxes[str]-2*a;
183          fixedString << this->starts[str]+1 << ":"
184                      << this->getEnd(str)+1;
185          this->sections[str] = fixedString.str();
186          doingBorders=true;
187          break;
188        case 2: // subsection involves a step
189        default:
190          readString>> a >> b >> c;
191          this->starts[str] = a-1;
192          this->dims[str] = b-a+1;
193          fixedString << a << ":" << b;
194          this->sections[str] = fixedString.str();
195          removeStep=true;
196          break;
197        }
198
199      }
200    }
201
202    if(removeStep){  // if there was a step present
203      errmsg.str("");
204      errmsg << "The subsection given is " << this->subsection <<".\n"
205             << "Duchamp is currently unable to deal with pixel steps"
206             << " in the subsection.\n"
207             << "These have been ignored, and so the subection used is ";
208    }
209
210    if(removeStep || doingBorders){
211      // rewrite subsection without any step sizes and with correct borders.
212      this->subsection = "[" + this->sections[0];
213      for(size_t str=1;str<numSections;str++)
214        this->subsection += ',' + this->sections[str];
215      this->subsection += "]";
216    }
217
218    if(removeStep){
219      errmsg << this->subsection << std::endl;
220      duchampWarning("Section parsing", errmsg.str());
221    }
222
223    return SUCCESS;
224 
225  }
226
227  std::string nullSection(int ndim)
228  {
229    std::stringstream ss;
230    ss << "[";
231    for(int i=0;i<ndim-1;i++) ss << "*,";
232    ss << "*]";
233    return ss.str();
234  }
235
236}
Note: See TracBrowser for help on using the repository browser.