source: trunk/src/Utils/Section.cc @ 526

Last change on this file since 526 was 507, checked in by MatthewWhiting, 16 years ago

Improvements and additions to the Section class.

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