source: tags/release-1.1.7/src/Detection/areClose.cc @ 1455

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

Adding the ChanMap? to the include statements

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/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        //       if(commonZ.isInScan(map1.getZ(),0)){
102       
103        for(int chanct2=0; (!close && (chanct2<nchan2)); chanct2++){
104          ChanMap map2=obj2.pixels().getChanMap(chanct2);
105          //      if(commonZ.isInScan(map2.getZ(),0)){
106       
107          if(abs(map1.getZ()-map2.getZ())<=threshV){
108             
109            Object2D temp1 = map1.getObject();
110            Object2D temp2 = map2.getObject();
111
112//          std::cerr << "Obj1:\n" << temp1 << "Obj2:\n" << temp2;
113             
114            if(flagAdj) gap = 1;
115            else gap = long( ceil(threshS) );
116            test1.define(0, temp1.getXmin()-gap,
117                         temp1.getXmax()-temp1.getXmin()+2*gap+1);
118            test2.define(0, temp2.getXmin(),
119                         temp2.getXmax()-temp2.getXmin()+1);
120            areNear = overlap(test1,test2);
121//          std::cerr << areNear;
122            test1.define(0, temp1.getYmin()-gap,
123                         temp1.getYmax()-temp1.getYmin()+2*gap+1);
124            test2.define(0, temp2.getYmin(),
125                         temp2.getYmax()-temp2.getYmin()+1);
126            areNear = areNear && overlap(test1,test2);
127//          std::cerr << areNear;
128             
129            if(areNear){
130              if(flagAdj) close = close || areAdj(temp1,temp2);
131              else close = close || areClose(temp1,temp2,threshS);
132            }
133           
134          }
135          //      }
136
137        }
138        //       }
139
140      }
141
142    }
143
144    return close;
145
146  }
147
148  bool areClose(Object2D &obj1, Object2D &obj2, float threshold)
149  {
150    bool close = false;
151
152    long nscan1 = obj1.getNumScan();
153    long nscan2 = obj2.getNumScan();
154
155    Scan temp1(0, obj1.getYmin()-int(threshold),
156               obj1.getYmax()-obj1.getYmin()+1+2*int(threshold));
157    Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
158    Scan Yoverlap = intersect(temp1,temp2);
159//       std::cerr << "\n"<<temp1 <<"\t" << temp2 << "\t" << Yoverlap<<"\n";
160     
161      // Xoverlap has the scans that overlap with a padding of width threshold
162      // If two pixels are separated in Y by threshold, but have the same X, then they match.
163      // This is the furthest apart they can be in Y.
164
165
166    if(Yoverlap.getXlen()>0){
167      // Grow by a pixel in each direction, to take into account the possibility of fractional thresholds (eg. 7.5)
168      Yoverlap.growLeft();
169      Yoverlap.growRight();
170   
171      // Now look at just these scans pixel by pixel
172
173      // Get the scans from object 2 that lie in the overlap region (these haven't been affected by the threshold gap)
174       for(int scanct2=0; (!close && (scanct2<nscan2)); scanct2++){
175        temp2 = obj2.getScan(scanct2);
176//      std::cerr << temp2.getY() << ":\n";
177        if(Yoverlap.isInScan(temp2.getY(),0)){ // if the scan is in the allowed Y range
178
179          for(int scanct1=0; (!close && (scanct1<nscan1)); scanct1++){
180            temp1 = obj1.getScan(scanct1);
181            long y = temp1.getY();
182//          std::cerr << temp1.getY() << " ";
183            if(abs(y-temp2.getY())<threshold){
184//            std::cerr << "("<<minSep(temp1,temp2)<<")";
185
186              close = (minSep(temp1,temp2) < threshold);
187
188            }
189
190          }
191//        std::cerr << "\n";
192
193        }
194
195       }
196     
197    }
198    return close;
199
200  }
201
202
203//   bool areClose(Object2D &obj1, Object2D &obj2, float threshold)
204//   {
205//     bool close = false;
206
207//     long nscan1 = obj1.getNumScan();
208//     long nscan2 = obj2.getNumScan();
209
210//     Scan temp1(0, obj1.getYmin()-int(threshold),
211//             obj1.getYmax()-obj1.getYmin()+1+2*int(threshold));
212//     Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
213//     Scan overlap = intersect(temp1,temp2);
214//       std::cerr << "\n"<<temp1 <<"\t" << temp2 << "\t" << overlap<<"\n";
215
216//     if(overlap.getXlen()>0){
217//       overlap.growLeft();
218//       overlap.growRight();
219
220//       std::cerr << nscan1 << " " << nscan2 << "    " << close << "\n";
221
222//       for(int scanct1=0; (!close && (scanct1<nscan1)); scanct1++){
223//      temp1 = obj1.getScan(scanct1);
224//      std::cerr << temp1.getY() << ":\n";
225// //   if(overlap.isInScan(temp1.getY(),0)){
226//      if(overlap.isInScan(temp1.getY()-threshold,0) || overlap.isInScan(temp1.getY()+threshold,0) ){
227//        long y1 = temp1.getY();
228
229
230//        for(int scanct2=0; (!close && (scanct2<nscan2)); scanct2++){
231//          temp2 = obj2.getScan(scanct2);
232//          if(overlap.isInScan(temp2.getY(),0)){
233//            long dy = abs(y1 - temp2.getY());
234
235//            std::cerr <<  temp2.getY() <<"  " << dy << "   ";
236     
237//            if(dy<=threshold){
238
239//              int gap = int(sqrt(threshold*threshold - dy*dy));
240//              Scan temp3(temp2.getY(),temp1.getX()-gap,temp1.getXlen()+2*gap);
241//              std::cerr << gap << "   " << temp3 << " <--> " << temp2;
242//              if(touching(temp3,temp2)) close = true;
243
244//            } // end of if(dy<thresh)
245
246//            std::cerr << "\n";
247
248//          }// if overlap.isIn(temp2)
249//        } // end of scanct2 loop
250
251//      } // if overlap.isIn(temp1)
252
253//       } // end of scanct1 loop
254
255//     } //end of if(overlap.getXlen()>0)
256
257//     return close;
258//   }
259
260  bool areAdj(Object2D &obj1, Object2D &obj2)
261  {
262    bool close = false;
263
264    long nscan1 = obj1.getNumScan();
265    long nscan2 = obj2.getNumScan();
266
267    Scan temp1(0, obj1.getYmin()-1,obj1.getYmax()-obj1.getYmin()+3);
268    Scan temp2(0, obj2.getYmin(),obj2.getYmax()-obj2.getYmin()+1);
269    Scan temp3;
270    Scan commonY = intersect(temp1,temp2);
271    if(commonY.getXlen()>0){
272      commonY.growLeft();
273      commonY.growRight();
274      //    std::cerr << temp1 << " " << temp2 << " " << commonY << "\n";
275
276      for(int scanct1=0;(!close && scanct1 < nscan1);scanct1++){
277        temp1 = obj1.getScan(scanct1);
278        if(commonY.isInScan(temp1.getY(),0)){
279          long y1 = temp1.getY();
280
281          for(int scanct2=0; (!close && scanct2 < nscan2); scanct2++){
282            temp2 = obj2.getScan(scanct2);
283            if(commonY.isInScan(temp2.getY(),0)){     
284              long dy = abs(y1 - temp2.getY());
285
286              if(dy<= 1){
287
288                temp3.define(temp2.getY(),temp1.getX(),temp1.getXlen());
289                if(touching(temp3,temp2)) close = true;
290
291              }
292            }
293          } // end of for loop over scanct2
294     
295        }
296     
297      } // end of for loop over scanct1
298
299    }
300    return close;
301  }
302
303}
Note: See TracBrowser for help on using the repository browser.