nodes: 0, module; 1, function_definition; 2, function_name:image_position_from_source; 3, parameters; 4, block; 5, identifier:self; 6, identifier:sourcePos_x; 7, identifier:sourcePos_y; 8, identifier:kwargs_lens; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, default_parameter; 15, default_parameter; 16, default_parameter; 17, default_parameter; 18, default_parameter; 19, expression_statement; 20, comment:# compute number of pixels to cover the search window with the required min_distance; 21, expression_statement; 22, expression_statement; 23, expression_statement; 24, expression_statement; 25, comment:# ray-shoot to find the relative distance to the required source position for each grid point; 26, expression_statement; 27, expression_statement; 28, comment:# select minima in the grid points and select grid points that do not deviate more than the; 29, comment:# width of the grid point to a solution of the lens equation; 30, expression_statement; 31, if_statement; 32, comment:#mag = np.abs(mag); 33, comment:#print(x_mins, y_mins, 'before requirement of min_distance'); 34, if_statement; 35, expression_statement; 36, expression_statement; 37, comment:# iterative solving of the lens equation for the selected grid points; 38, expression_statement; 39, comment:# only select iterative results that match the precision limit; 40, expression_statement; 41, expression_statement; 42, comment:# find redundant solutions within the min_distance criterion; 43, expression_statement; 44, if_statement; 45, comment:#x_mins, y_mins = lenstronomy_util.coordInImage(x_mins, y_mins, numPix, deltapix); 46, return_statement; 47, identifier:min_distance; 48, float:0.1; 49, identifier:search_window; 50, integer:10; 51, identifier:precision_limit; 52, binary_operator:10**(-10); 53, identifier:num_iter_max; 54, integer:100; 55, identifier:arrival_time_sort; 56, True; 57, identifier:initial_guess_cut; 58, True; 59, identifier:verbose; 60, False; 61, identifier:x_center; 62, integer:0; 63, identifier:y_center; 64, integer:0; 65, identifier:num_random; 66, integer:0; 67, comment:"""
          finds image position source position and lense model
  
          :param sourcePos_x: source position in units of angle
          :param sourcePos_y: source position in units of angle
          :param kwargs_lens: lens model parameters as keyword arguments
          :param min_distance: minimum separation to consider for two images in units of angle
          :param search_window: window size to be considered by the solver. Will not find image position outside this window
          :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
          :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
          :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
          :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on distance criteria from the source position
          :param verbose: bool, if True, prints some useful information for the user
          :param x_center: float, center of the window to search for point sources
          :param y_center: float, center of the window to search for point sources
          :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
          :raises: AttributeError, KeyError
          """; 68, assignment; 69, assignment; 70, augmented_assignment; 71, augmented_assignment; 72, assignment; 73, assignment; 74, assignment; 75, comparison_operator:verbose is True; 76, block; 77, comparison_operator:initial_guess_cut is True; 78, block; 79, assignment; 80, assignment; 81, assignment; 82, assignment; 83, assignment; 84, assignment; 85, comparison_operator:arrival_time_sort is True; 86, block; 87, expression_list; 88, integer:10; 89, parenthesized_expression; 90, identifier:numPix; 91, call; 92, pattern_list; 93, call; 94, identifier:x_grid; 95, identifier:x_center; 96, identifier:y_grid; 97, identifier:y_center; 98, pattern_list; 99, call; 100, identifier:absmapped; 101, call; 102, pattern_list; 103, call; 104, identifier:verbose; 105, True; 106, expression_statement; 107, identifier:initial_guess_cut; 108, True; 109, expression_statement; 110, expression_statement; 111, expression_statement; 112, expression_statement; 113, if_statement; 114, identifier:x_mins; 115, call; 116, identifier:y_mins; 117, call; 118, pattern_list; 119, call; 120, identifier:x_mins; 121, subscript; 122, identifier:y_mins; 123, subscript; 124, pattern_list; 125, call; 126, identifier:arrival_time_sort; 127, True; 128, expression_statement; 129, identifier:x_mins; 130, identifier:y_mins; 131, unary_operator; 132, identifier:int; 133, argument_list; 134, identifier:x_grid; 135, identifier:y_grid; 136, attribute; 137, argument_list; 138, identifier:x_mapped; 139, identifier:y_mapped; 140, attribute; 141, argument_list; 142, attribute; 143, argument_list; 144, identifier:x_mins; 145, identifier:y_mins; 146, identifier:delta_map; 147, attribute; 148, argument_list; 149, call; 150, assignment; 151, assignment; 152, assignment; 153, assignment; 154, comparison_operator:verbose is True; 155, block; 156, attribute; 157, argument_list; 158, attribute; 159, argument_list; 160, identifier:x_mins; 161, identifier:y_mins; 162, identifier:solver_precision; 163, attribute; 164, argument_list; 165, identifier:x_mins; 166, comparison_operator:solver_precision <= precision_limit; 167, identifier:y_mins; 168, comparison_operator:solver_precision <= precision_limit; 169, identifier:x_mins; 170, identifier:y_mins; 171, attribute; 172, argument_list; 173, assignment; 174, integer:10; 175, binary_operator:round(search_window / min_distance) + 0.5; 176, identifier:util; 177, identifier:make_grid; 178, identifier:numPix; 179, identifier:min_distance; 180, attribute; 181, identifier:ray_shooting; 182, identifier:x_grid; 183, identifier:y_grid; 184, identifier:kwargs_lens; 185, identifier:util; 186, identifier:displaceAbs; 187, identifier:x_mapped; 188, identifier:y_mapped; 189, identifier:sourcePos_x; 190, identifier:sourcePos_y; 191, identifier:util; 192, identifier:neighborSelect; 193, identifier:absmapped; 194, identifier:x_grid; 195, identifier:y_grid; 196, identifier:print; 197, argument_list; 198, identifier:mag; 199, call; 200, subscript; 201, integer:1; 202, identifier:x_mins; 203, subscript; 204, identifier:y_mins; 205, subscript; 206, identifier:verbose; 207, True; 208, expression_statement; 209, identifier:np; 210, identifier:append; 211, identifier:x_mins; 212, call; 213, identifier:np; 214, identifier:append; 215, identifier:y_mins; 216, call; 217, identifier:self; 218, identifier:_findIterative; 219, identifier:x_mins; 220, identifier:y_mins; 221, identifier:sourcePos_x; 222, identifier:sourcePos_y; 223, identifier:kwargs_lens; 224, identifier:precision_limit; 225, identifier:num_iter_max; 226, keyword_argument; 227, keyword_argument; 228, identifier:solver_precision; 229, identifier:precision_limit; 230, identifier:solver_precision; 231, identifier:precision_limit; 232, identifier:image_util; 233, identifier:findOverlap; 234, identifier:x_mins; 235, identifier:y_mins; 236, identifier:min_distance; 237, pattern_list; 238, call; 239, call; 240, float:0.5; 241, identifier:self; 242, identifier:lensModel; 243, binary_operator:"There are %s regions identified that could contain a solution of the lens equation" % len(x_mins); 244, attribute; 245, argument_list; 246, identifier:mag; 247, comparison_operator:mag < 1; 248, identifier:x_mins; 249, comparison_operator:delta_map <= min_distance*mag*5; 250, identifier:y_mins; 251, comparison_operator:delta_map <= min_distance*mag*5; 252, call; 253, attribute; 254, argument_list; 255, attribute; 256, argument_list; 257, identifier:verbose; 258, identifier:verbose; 259, identifier:min_distance; 260, identifier:min_distance; 261, identifier:x_mins; 262, identifier:y_mins; 263, attribute; 264, argument_list; 265, identifier:round; 266, argument_list; 267, string:"There are %s regions identified that could contain a solution of the lens equation"; 268, call; 269, identifier:np; 270, identifier:abs; 271, call; 272, identifier:mag; 273, integer:1; 274, identifier:delta_map; 275, binary_operator:min_distance*mag*5; 276, identifier:delta_map; 277, binary_operator:min_distance*mag*5; 278, identifier:print; 279, argument_list; 280, attribute; 281, identifier:uniform; 282, keyword_argument; 283, keyword_argument; 284, keyword_argument; 285, attribute; 286, identifier:uniform; 287, keyword_argument; 288, keyword_argument; 289, keyword_argument; 290, identifier:self; 291, identifier:sort_arrival_times; 292, identifier:x_mins; 293, identifier:y_mins; 294, identifier:kwargs_lens; 295, binary_operator:search_window / min_distance; 296, identifier:len; 297, argument_list; 298, attribute; 299, argument_list; 300, binary_operator:min_distance*mag; 301, integer:5; 302, binary_operator:min_distance*mag; 303, integer:5; 304, binary_operator:"The number of regions that meet the plausibility criteria are %s" % len(x_mins); 305, identifier:np; 306, identifier:random; 307, identifier:low; 308, binary_operator:-search_window/2+x_center; 309, identifier:high; 310, binary_operator:search_window/2+x_center; 311, identifier:size; 312, identifier:num_random; 313, identifier:np; 314, identifier:random; 315, identifier:low; 316, binary_operator:-search_window / 2 + y_center; 317, identifier:high; 318, binary_operator:search_window / 2 + y_center; 319, identifier:size; 320, identifier:num_random; 321, identifier:search_window; 322, identifier:min_distance; 323, identifier:x_mins; 324, attribute; 325, identifier:magnification; 326, identifier:x_mins; 327, identifier:y_mins; 328, identifier:kwargs_lens; 329, identifier:min_distance; 330, identifier:mag; 331, identifier:min_distance; 332, identifier:mag; 333, string:"The number of regions that meet the plausibility criteria are %s"; 334, call; 335, binary_operator:-search_window/2; 336, identifier:x_center; 337, binary_operator:search_window/2; 338, identifier:x_center; 339, binary_operator:-search_window / 2; 340, identifier:y_center; 341, binary_operator:search_window / 2; 342, identifier:y_center; 343, identifier:self; 344, identifier:lensModel; 345, identifier:len; 346, argument_list; 347, unary_operator; 348, integer:2; 349, identifier:search_window; 350, integer:2; 351, unary_operator; 352, integer:2; 353, identifier:search_window; 354, integer:2; 355, identifier:x_mins; 356, identifier:search_window; 357, identifier:search_window
code: def image_position_from_source(self, sourcePos_x, sourcePos_y, kwargs_lens, min_distance=0.1, search_window=10,
                                     precision_limit=10**(-10), num_iter_max=100, arrival_time_sort=True,
                                     initial_guess_cut=True, verbose=False, x_center=0, y_center=0, num_random=0):
          """
          finds image position source position and lense model
  
          :param sourcePos_x: source position in units of angle
          :param sourcePos_y: source position in units of angle
          :param kwargs_lens: lens model parameters as keyword arguments
          :param min_distance: minimum separation to consider for two images in units of angle
          :param search_window: window size to be considered by the solver. Will not find image position outside this window
          :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
          :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
          :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
          :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on distance criteria from the source position
          :param verbose: bool, if True, prints some useful information for the user
          :param x_center: float, center of the window to search for point sources
          :param y_center: float, center of the window to search for point sources
          :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
          :raises: AttributeError, KeyError
          """
  
          # compute number of pixels to cover the search window with the required min_distance
          numPix = int(round(search_window / min_distance) + 0.5)
          x_grid, y_grid = util.make_grid(numPix, min_distance)
          x_grid += x_center
          y_grid += y_center
          # ray-shoot to find the relative distance to the required source position for each grid point
          x_mapped, y_mapped = self.lensModel.ray_shooting(x_grid, y_grid, kwargs_lens)
          absmapped = util.displaceAbs(x_mapped, y_mapped, sourcePos_x, sourcePos_y)
          # select minima in the grid points and select grid points that do not deviate more than the
          # width of the grid point to a solution of the lens equation
          x_mins, y_mins, delta_map = util.neighborSelect(absmapped, x_grid, y_grid)
          if verbose is True:
              print("There are %s regions identified that could contain a solution of the lens equation" % len(x_mins))
          #mag = np.abs(mag)
          #print(x_mins, y_mins, 'before requirement of min_distance')
          if initial_guess_cut is True:
              mag = np.abs(self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
              mag[mag < 1] = 1
              x_mins = x_mins[delta_map <= min_distance*mag*5]
              y_mins = y_mins[delta_map <= min_distance*mag*5]
              if verbose is True:
                  print("The number of regions that meet the plausibility criteria are %s" % len(x_mins))
          x_mins = np.append(x_mins, np.random.uniform(low=-search_window/2+x_center, high=search_window/2+x_center,
                                                       size=num_random))
          y_mins = np.append(y_mins, np.random.uniform(low=-search_window / 2 + y_center, high=search_window / 2 + y_center,
                                               size=num_random))
          # iterative solving of the lens equation for the selected grid points
          x_mins, y_mins, solver_precision = self._findIterative(x_mins, y_mins, sourcePos_x, sourcePos_y, kwargs_lens,
                                                                 precision_limit, num_iter_max, verbose=verbose,
                                                                 min_distance=min_distance)
          # only select iterative results that match the precision limit
          x_mins = x_mins[solver_precision <= precision_limit]
          y_mins = y_mins[solver_precision <= precision_limit]
          # find redundant solutions within the min_distance criterion
          x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
          if arrival_time_sort is True:
              x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins, kwargs_lens)
          #x_mins, y_mins = lenstronomy_util.coordInImage(x_mins, y_mins, numPix, deltapix)
          return x_mins, y_mins