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

Last change on this file since 621 was 541, checked in by MatthewWhiting, 15 years ago

Changing all calls of uint to unsigned int, as there are sometimes compilers that don't know about that typedef. Also added an include call for stdlib.h to fitsHeader.cc so that it knows about calloc.

File size: 7.1 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(unsigned int 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(unsigned int 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(unsigned int 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(unsigned int 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(unsigned int 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.