source: trunk/src/Detection/areClose.cc @ 528

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

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

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