//  [python]
def refine_feature_op(self, points, feature_map, name):

        h, w = t.cast(t.shape(feature_map)[1], t.int32), t.cast(t.shape(feature_map)[2], t.int32)

        xmin = t.maximum(0.0, t.floor(points[:, 0]))
        xmin = t.minimum(t.cast(w - 1, t.float32), t.ceil(xmin))

        ymin = t.maximum(0.0, t.floor(points[:, 1]))
        ymin = t.minimum(t.cast(h - 1, t.float32), t.ceil(ymin))

        xmax = t.minimum(t.cast(w - 1, t.float32), t.ceil(points[:, 0]))
        xmax = t.maximum(0.0, t.floor(xmax))

        ymax = t.minimum(t.cast(h - 1, t.float32), t.ceil(points[:, 1]))
        ymax = t.maximum(0.0, t.floor(ymax))

        left_top = t.cast(t.transpose(t.stack([ymin, xmin], axis=0)), t.int32)
        right_bottom = t.cast(t.transpose(t.stack([ymax, xmax], axis=0)), t.int32)
        left_bottom = t.cast(t.transpose(t.stack([ymax, xmin], axis=0)), t.int32)
        right_top = t.cast(t.transpose(t.stack([ymin, xmax], axis=0)), t.int32)

        feature_1x5 = slim.conv2d(inputs=feature_map,
                                  num_outputs=cfgs.FPN_CHANNEL,
                                  kernel_size=[1, 5],
                                  weights_initializer=cfgs.SUBNETS_WEIGHTS_INITIALIZER,
                                  biases_initializer=cfgs.SUBNETS_BIAS_INITIALIZER,
                                  stride=1,
                                  activation_fn=None,
                                  scope='refine_1x5_{}'.format(name))

        feature5x1 = slim.conv2d(inputs=feature_1x5,
                                 num_outputs=cfgs.FPN_CHANNEL,
                                 kernel_size=[5, 1],
                                 weights_initializer=cfgs.SUBNETS_WEIGHTS_INITIALIZER,
                                 biases_initializer=cfgs.SUBNETS_BIAS_INITIALIZER,
                                 stride=1,
                                 activation_fn=None,
                                 scope='refine_5x1_{}'.format(name))

        feature_1x1 = slim.conv2d(inputs=feature_map,
                                  num_outputs=cfgs.FPN_CHANNEL,
                                  kernel_size=[1, 1],
                                  weights_initializer=cfgs.SUBNETS_WEIGHTS_INITIALIZER,
                                  biases_initializer=cfgs.SUBNETS_BIAS_INITIALIZER,
                                  stride=1,
                                  activation_fn=None,
                                  scope='refine_1x1_{}'.format(name))

        feature = feature5x1 + feature_1x1
        # feature = feature_map

        left_top_feature = t.gather_nd(t.squeeze(feature), left_top)
        right_bottom_feature = t.gather_nd(t.squeeze(feature), right_bottom)
        left_bottom_feature = t.gather_nd(t.squeeze(feature), left_bottom)
        right_top_feature = t.gather_nd(t.squeeze(feature), right_top)

        refine_feature = right_bottom_feature * t.tile(
            t.reshape((t.abs((points[:, 0] - xmin) * (points[:, 1] - ymin))), [-1, 1]),
            [1, cfgs.FPN_CHANNEL]) \
                         + left_top_feature * t.tile(
            t.reshape((t.abs((xmax - points[:, 0]) * (ymax - points[:, 1]))), [-1, 1]),
            [1, cfgs.FPN_CHANNEL]) \
                         + right_top_feature * t.tile(
            t.reshape((t.abs((points[:, 0] - xmin) * (ymax - points[:, 1]))), [-1, 1]),
            [1, cfgs.FPN_CHANNEL]) \
                         + left_bottom_feature * t.tile(
            t.reshape((t.abs((xmax - points[:, 0]) * (points[:, 1] - ymin))), [-1, 1]),
            [1, cfgs.FPN_CHANNEL])

        refine_feature = t.reshape(refine_feature, [1, t.cast(h, t.int32), t.cast(w, t.int32), cfgs.FPN_CHANNEL])

        # refine_feature = t.reshape(refine_feature, [1, t.cast(feature_size[1], t.int32),
        #                                              t.cast(feature_size[0], t.int32), 256])

        return refine_feature + feature