source: branches/pixelmap-refactor-branch/src/Detection/areClose.cc @ 549

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

Making sure overloaded functions still work, and removing all instances of pixels()

File size: 9.5 KB
Line 
1// -----------------------------------------------------------------------
2// areClose.cc: Determine whether two Detections are close enough to
3//              be merged.
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 <math.h>
30#include <duchamp/Detection/detection.hh>
31#include <duchamp/PixelMap/Scan.hh>
32#include <duchamp/PixelMap/ChanMap.hh>
33#include <duchamp/PixelMap/Object3D.hh>
34#include <duchamp/param.hh>
35
36using namespace PixelInfo;
37
38namespace duchamp
39{
40
41  bool areAdj(Object2D &obj1, Object2D &obj2);
42  bool areClose(Object2D &obj1, Object2D &obj2, float threshold);
43
44  bool areClose(Detection &obj1, Detection &obj2, Param &par)
45  {
46
47    /// A Function to test whether object1 and object2 are within the
48    /// spatial and velocity thresholds specified in the parameter set par.
49    /// Returns true if at least one pixel of object1 is close to
50    /// at least one pixel of object2.
51 
52    bool close = false;   // this will be the value returned
53
54    //
55    // First, check to see if the objects are nearby.  We will only do
56    // the pixel-by-pixel comparison if their pixel ranges overlap.
57    // This saves a bit of time if the objects are big and are nowhere
58    // near one another.
59    //
60
61    bool flagAdj = par.getFlagAdjacent();
62    float threshS = par.getThreshS();
63    float threshV = par.getThreshV();
64
65    long gap;
66    if(flagAdj) gap = 1;
67    else gap = long( ceil(threshS) );
68
69    Scan test1,test2;
70
71    // Test X ranges
72    test1.define(0,obj1.getXmin()-gap,obj1.getXmax()-obj1.getXmin()+2*gap+1);
73    test2.define(0,obj2.getXmin(),obj2.getXmax()-obj2.getXmin()+1);
74    bool areNear = overlap(test1,test2);
75
76    // Test Y ranges
77    test1.define(0,obj1.getYmin()-gap,obj1.getYmax()-obj1.getYmin()+2*gap+1);
78    test2.define(0,obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
79    areNear = areNear && overlap(test1,test2);
80 
81    // Test Z ranges
82    gap = long(ceil(threshV));
83    test1.define(0,obj1.getZmin()-gap,obj1.getZmax()-obj1.getZmin()+2*gap+1);
84    test2.define(0,obj2.getZmin(),obj2.getZmax()-obj2.getZmin()+1);
85    areNear = areNear && overlap(test1,test2);
86    //   Scan commonZ = intersect(test1,test2);
87
88    if(areNear){
89      //
90      // If we get to here, the pixel ranges overlap -- so we do a
91      // pixel-by-pixel comparison to make sure they are actually
92      // "close" according to the thresholds.  Otherwise, close=false,
93      // and so don't need to do anything else before returning.
94      //
95
96      long nchan1 = obj1.getNumChannels();
97      long nchan2 = obj2.getNumChannels();
98
99      for(int chanct1=0; (!close && (chanct1<nchan1)); chanct1++){
100//      ChanMap map1=obj1.pixels().getChanMap(chanct1);
101        ChanMap map1=obj1.getChanMap(chanct1);
102        //       if(commonZ.isInScan(map1.getZ(),0)){
103       
104        for(int chanct2=0; (!close && (chanct2<nchan2)); chanct2++){
105//        ChanMap map2=obj2.pixels().getChanMap(chanct2);
106          ChanMap map2=obj2.getChanMap(chanct2);
107          //      if(commonZ.isInScan(map2.getZ(),0)){
108       
109          if(abs(map1.getZ()-map2.getZ())<=threshV){
110             
111            Object2D temp1 = map1.getObject();
112            Object2D temp2 = map2.getObject();
113
114//          std::cerr << "Obj1:\n" << temp1 << "Obj2:\n" << temp2;
115             
116            if(flagAdj) gap = 1;
117            else gap = long( ceil(threshS) );
118            test1.define(0, temp1.getXmin()-gap,
119                         temp1.getXmax()-temp1.getXmin()+2*gap+1);
120            test2.define(0, temp2.getXmin(),
121                         temp2.getXmax()-temp2.getXmin()+1);
122            areNear = overlap(test1,test2);
123//          std::cerr << areNear;
124            test1.define(0, temp1.getYmin()-gap,
125                         temp1.getYmax()-temp1.getYmin()+2*gap+1);
126            test2.define(0, temp2.getYmin(),
127                         temp2.getYmax()-temp2.getYmin()+1);
128            areNear = areNear && overlap(test1,test2);
129//          std::cerr << areNear;
130             
131            if(areNear){
132              if(flagAdj) close = close || areAdj(temp1,temp2);
133              else close = close || areClose(temp1,temp2,threshS);
134            }
135           
136          }
137          //      }
138
139        }
140        //       }
141
142      }
143
144    }
145
146    return close;
147
148  }
149
150  bool areClose(Object2D &obj1, Object2D &obj2, float threshold)
151  {
152    bool close = false;
153
154    long nscan1 = obj1.getNumScan();
155    long nscan2 = obj2.getNumScan();
156
157    Scan temp1(0, obj1.getYmin()-int(threshold),
158               obj1.getYmax()-obj1.getYmin()+1+2*int(threshold));
159    Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
160    Scan Yoverlap = intersect(temp1,temp2);
161//       std::cerr << "\n"<<temp1 <<"\t" << temp2 << "\t" << Yoverlap<<"\n";
162     
163      // Xoverlap has the scans that overlap with a padding of width threshold
164      // If two pixels are separated in Y by threshold, but have the same X, then they match.
165      // This is the furthest apart they can be in Y.
166
167
168    if(Yoverlap.getXlen()>0){
169      // Grow by a pixel in each direction, to take into account the possibility of fractional thresholds (eg. 7.5)
170      Yoverlap.growLeft();
171      Yoverlap.growRight();
172   
173      // Now look at just these scans pixel by pixel
174
175      // Get the scans from object 2 that lie in the overlap region (these haven't been affected by the threshold gap)
176       for(int scanct2=0; (!close && (scanct2<nscan2)); scanct2++){
177        temp2 = obj2.getScan(scanct2);
178//      std::cerr << temp2.getY() << ":\n";
179        if(Yoverlap.isInScan(temp2.getY(),0)){ // if the scan is in the allowed Y range
180
181          for(int scanct1=0; (!close && (scanct1<nscan1)); scanct1++){
182            temp1 = obj1.getScan(scanct1);
183            long y = temp1.getY();
184//          std::cerr << temp1.getY() << " ";
185            if(abs(y-temp2.getY())<threshold){
186//            std::cerr << "("<<minSep(temp1,temp2)<<")";
187
188              close = (minSep(temp1,temp2) < threshold);
189
190            }
191
192          }
193//        std::cerr << "\n";
194
195        }
196
197       }
198     
199    }
200    return close;
201
202  }
203
204
205//   bool areClose(Object2D &obj1, Object2D &obj2, float threshold)
206//   {
207//     bool close = false;
208
209//     long nscan1 = obj1.getNumScan();
210//     long nscan2 = obj2.getNumScan();
211
212//     Scan temp1(0, obj1.getYmin()-int(threshold),
213//             obj1.getYmax()-obj1.getYmin()+1+2*int(threshold));
214//     Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
215//     Scan overlap = intersect(temp1,temp2);
216//       std::cerr << "\n"<<temp1 <<"\t" << temp2 << "\t" << overlap<<"\n";
217
218//     if(overlap.getXlen()>0){
219//       overlap.growLeft();
220//       overlap.growRight();
221
222//       std::cerr << nscan1 << " " << nscan2 << "    " << close << "\n";
223
224//       for(int scanct1=0; (!close && (scanct1<nscan1)); scanct1++){
225//      temp1 = obj1.getScan(scanct1);
226//      std::cerr << temp1.getY() << ":\n";
227// //   if(overlap.isInScan(temp1.getY(),0)){
228//      if(overlap.isInScan(temp1.getY()-threshold,0) || overlap.isInScan(temp1.getY()+threshold,0) ){
229//        long y1 = temp1.getY();
230
231
232//        for(int scanct2=0; (!close && (scanct2<nscan2)); scanct2++){
233//          temp2 = obj2.getScan(scanct2);
234//          if(overlap.isInScan(temp2.getY(),0)){
235//            long dy = abs(y1 - temp2.getY());
236
237//            std::cerr <<  temp2.getY() <<"  " << dy << "   ";
238     
239//            if(dy<=threshold){
240
241//              int gap = int(sqrt(threshold*threshold - dy*dy));
242//              Scan temp3(temp2.getY(),temp1.getX()-gap,temp1.getXlen()+2*gap);
243//              std::cerr << gap << "   " << temp3 << " <--> " << temp2;
244//              if(touching(temp3,temp2)) close = true;
245
246//            } // end of if(dy<thresh)
247
248//            std::cerr << "\n";
249
250//          }// if overlap.isIn(temp2)
251//        } // end of scanct2 loop
252
253//      } // if overlap.isIn(temp1)
254
255//       } // end of scanct1 loop
256
257//     } //end of if(overlap.getXlen()>0)
258
259//     return close;
260//   }
261
262  bool areAdj(Object2D &obj1, Object2D &obj2)
263  {
264    bool close = false;
265
266    long nscan1 = obj1.getNumScan();
267    long nscan2 = obj2.getNumScan();
268
269    Scan temp1(0, obj1.getYmin()-1,obj1.getYmax()-obj1.getYmin()+3);
270    Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
271    Scan temp3;
272    Scan commonY = intersect(temp1,temp2);
273    if(commonY.getXlen()>0){
274      commonY.growLeft();
275      commonY.growRight();
276      //    std::cerr << temp1 << " " << temp2 << " " << commonY << "\n";
277
278      for(int scanct1=0;(!close && scanct1 < nscan1);scanct1++){
279        temp1 = obj1.getScan(scanct1);
280        if(commonY.isInScan(temp1.getY(),0)){
281          long y1 = temp1.getY();
282
283          for(int scanct2=0; (!close && scanct2 < nscan2); scanct2++){
284            temp2 = obj2.getScan(scanct2);
285            if(commonY.isInScan(temp2.getY(),0)){     
286              long dy = abs(y1 - temp2.getY());
287
288              if(dy<= 1){
289
290                temp3.define(temp2.getY(),temp1.getX(),temp1.getXlen());
291                if(touching(temp3,temp2)) close = true;
292
293              }
294            }
295          } // end of for loop over scanct2
296     
297        }
298     
299      } // end of for loop over scanct1
300
301    }
302    return close;
303  }
304
305}
Note: See TracBrowser for help on using the repository browser.