source: tags/release-1.1.7/src/Utils/Section.cc @ 1455

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

Including the recent minor changes to 1.1.7.

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