Exemple #1
0
def v_θ_deriv_splitter(soln, cutoff=DEFAULT_SPLITTER_CUTOFF, **kwargs):
    """
    Use derivative of v_θ to determine type of solution
    """
    # pylint: disable=unused-argument
    v_θ = soln.solution[:, ODEIndex.v_θ]
    if soln.internal_data is not None:
        problems = soln.internal_data.problems
        if any("negative velocity" in pl for pl in problems.values()):
            return SplitterStatus.SIGN_FLIP
    else:
        log.notice("Skipping checking problems due to no internal data")

    if soln.internal_data is not None:
        deriv_v_θ = soln.internal_data.derivs[ODEIndex.v_θ]
        if any(diff(deriv_v_θ, 2) > 0):
            return SplitterStatus.DIVERGE
        if any(diff(deriv_v_θ) < 0):
            return SplitterStatus.SIGN_FLIP

    v_θ_near_sonic = np_and(v_θ > cutoff, v_θ < 1)
    if not np_any(v_θ_near_sonic):
        return SplitterStatus.SIGN_FLIP

    v_θ_above_sonic = v_θ > 1
    if np_any(v_θ_above_sonic):
        return SplitterStatus.DIVERGE

    d_v_θ = diff(v_θ[v_θ_near_sonic])
    if np_all(d_v_θ > 0):
        return SplitterStatus.DIVERGE
    return SplitterStatus.SIGN_FLIP
Exemple #2
0
 def compute(self, today, assets, out, value):
     if isinstance(value, LabelArray):
         out[:] = ~np_any(value.is_missing(), axis=0)
     else:
         out[:] = ~np_any(
             is_missing(value, self.inputs[0].missing_value),
             axis=0,
         )
Exemple #3
0
 def compute(self, today, assets, out, value):
     if isinstance(value, LabelArray):
         out[:] = ~np_any(value.is_missing(), axis=0)
     else:
         out[:] = ~np_any(
             is_missing(value, self.inputs[0].missing_value),
             axis=0,
         )
Exemple #4
0
def components(ax, massAcid, alk0Sim, alkSim, sublabel):
    """Every component of alkalinity throughout a titration."""
    ax.plot(massAcid * 1e3,
            -log10(alk0Sim),
            label='Total alk.',
            marker='o',
            markersize=3,
            c='k',
            clip_on=False)
    for component in alkSim[1].keys():
        if component.startswith('-'):  # this is a bit sketchy
            yVar = -alkSim[1][component]
        else:
            yVar = alkSim[1][component]
        if np_any(yVar > 0):
            ax.plot(massAcid * 1e3,
                    -log10(yVar),
                    label=rgbs_names[component][1],
                    marker='x',
                    markersize=3,
                    c=rgbs_names[component][0],
                    clip_on=False)
    ax.set_xlim([0, np_max(massAcid) * 1e3])
    ax.set_ylim(ax.get_ylim()[::-1])
    ax.legend(bbox_to_anchor=(1.05, 1))
    ax.set_xlabel('Acid mass / g')
    ax.set_ylabel('$-$log$_{10}$(concentration from pH / mol$\cdot$kg$^{-1}$)')
    ax.set_title(sublabel, fontsize=10)
    return ax
def check_agg_error(data):
    '''
    检查是否有数据在pivot_table中使用了join
    '''
    for row in data.iterrows():
        if np_any(row[1].str.contains(';')):
            raise ValueError('\'join\' has been performed!')
Exemple #6
0
def validate_solution(soln):
    """
    Check that the solution returned is valid, even if the ode solver returned
    success
    """
    if soln.flag != StatusEnum.SUCCESS:
        return soln, False
    v_θ = soln.solution[:, ODEIndex.v_θ]
    ρ = soln.solution[:, ODEIndex.ρ]
    if np_any(v_θ < 0):
        return soln, False
    if np_any(diff(v_θ) < 0):
        return soln, False
    if np_any(ρ < 0):
        return soln, False
    return soln, True
Exemple #7
0
def alkComponents(titrationPotentiometric, ax=None):
    t = titrationPotentiometric
    assert 'alkSteps' in vars(t), \
        'You must first run `titrationPotentiometric.get_alkSteps().`'
    # Get the 'used' values
    solver = 'complete'  # only valid option for now
    usedMin = np_min(t.volAcid[t.solvedWith[solver]])
    usedMax = np_max(t.volAcid[t.solvedWith[solver]])
    # Draw the plot
    ax = _checksetax(ax)
    ax.plot(t.volAcid,
            -log10(t.alkSteps),
            label='Total alk.',
            marker='o',
            markersize=_markersize,
            c='k',
            alpha=_alpha)
    for component, conc in t.alkComponents.items():
        if np_any(conc != 0):
            ax.plot(t.volAcid, -log10(np_abs(conc)), **rgbs[component])
    ax.add_patch(
        patches.Rectangle((usedMin, ax.get_ylim()[1]),
                          usedMax - usedMin,
                          ax.get_ylim()[0] - ax.get_ylim()[1],
                          facecolor=0.9 * ones(3)))
    ax.invert_yaxis()
    ax.legend(bbox_to_anchor=(1.05, 1), edgecolor='k')
    ax.set_xlabel('Acid volume / ml')
    ax.set_ylabel('$-$log$_{10}$(concentration from pH / mol$\cdot$kg$^{-1}$)')
    return ax
Exemple #8
0
def pHfromTAfCO2(TA, fCO2, K0, K1, K2, KW, KB, KF, KS, KP1, KP2, KP3, KSi,
                 KNH3, KH2S, TB, TF, TS, TP, TSi, TNH3, TH2S):
    """Calculate pH from total alkalinity and CO2 fugacity.

    This calculates pH from TA and fCO2 using K1 and K2 by Newton's method.
    It tries to solve for the pH at which Residual = 0.
    The starting guess is pH = 8.
    Though it is coded for H on the total pH scale, for the pH values occuring
    in seawater (pH > 6) it will be equally valid on any pH scale (H terms
    negligible) as long as the K Constants are on that scale.

    Based on CalculatepHfromTAfCO2, version 04.01, 10-13-97, by Ernie Lewis.
    """
    pHGuess = 8.0  # this is the first guess
    pH = full_like(TA, pHGuess)  # first guess for all samples
    deltapH = 1 + pHTol
    ln10 = log(10)
    while np_any(np_abs(deltapH) > pHTol):
        H = 10.0**-pH
        HCO3 = K0 * K1 * fCO2 / H
        CO3 = K0 * K1 * K2 * fCO2 / H**2
        CAlk = HCO3 + 2 * CO3
        _, _, BAlk, OH, PAlk, SiAlk, NH3Alk, H2SAlk, Hfree, HSO4, HF = \
            AlkParts(pH, 0.0,
                K1, K2, KW, KB, KF, KS, KP1, KP2, KP3, KSi, KNH3, KH2S,
                TB, TF, TS, TP, TSi, TNH3, TH2S)
        Residual = (TA - CAlk - BAlk - OH - PAlk - SiAlk - NH3Alk - H2SAlk +
                    Hfree + HSO4 + HF)
        # Find Slope dTA/dpH (this is not exact, but keeps all important terms)
        Slope = ln10 * (HCO3 + 4 * CO3 + BAlk * H / (KB + H) + OH + H)
        deltapH = Residual / Slope  # this is Newton's method
        # To keep the jump from being too big:
        while np_any(np_abs(deltapH) > 1):
            FF = np_abs(deltapH) > 1
            if any(FF):
                deltapH[FF] /= 2
        # The following logical means that each row stops updating once its
        # deltapH value is beneath the pHTol threshold, instead of continuing
        # to update ALL rows until they all meet the threshold.
        # This approach avoids the problem of reaching a different
        # answer for a given set of input conditions depending on how many
        # iterations the other input rows take to solve. // MPH
        F = np_abs(deltapH) > pHTol
        pH[F] += deltapH[F]
    return pH
Exemple #9
0
def is_solution_best(soln):
    """
    Determine if solution is best possible solution
    """
    soln, valid = validate_solution(soln)
    if not valid:
        return soln, False

    v_θ = soln.solution[:, ODEIndex.v_θ]

    v_θ_near_sonic = np_and(v_θ > DEFAULT_SPLITTER_CUTOFF, v_θ < 1)
    if not np_any(v_θ_near_sonic):
        return soln, False

    if np_any(diff(v_θ[v_θ_near_sonic], n=2)) > 0:
        return soln, False

    return soln, True
Exemple #10
0
def get_all_sonic_points(solution):
    """
    Get the angles at which the mhd sonic points occurs
    """
    slow_mach, sonic_mach, alfven_mach, fast_mach = get_mach_numbers(solution)
    angles = solution.angles
    if np_any(slow_mach > 1.0):
        slow_angle = interp1d(slow_mach, angles)(1.0)
    else:
        slow_angle = None
    if np_any(sonic_mach > 1.0):
        sonic_angle = interp1d(sonic_mach, angles)(1.0)
    else:
        sonic_angle = None
    if np_any(alfven_mach > 1.0):
        alfven_angle = interp1d(alfven_mach, angles)(1.0)
    else:
        alfven_angle = None
    if np_any(fast_mach > 1.0):
        fast_angle = interp1d(fast_mach, angles)(1.0)
    else:
        fast_angle = None
    return slow_angle, sonic_angle, alfven_angle, fast_angle
Exemple #11
0
    def train_epoch(self, input_train, target_train):
        centers = self.centers
        old_centers = centers.copy()
        output_train = self.predict(input_train)

        for i, center in enumerate(centers):
            positions = argwhere(output_train[:, 0] == i)

            if not np_any(positions):
                continue

            class_data = take(input_train, positions, axis=0)
            centers[i, :] = (1 / len(class_data)) * np_sum(class_data, axis=0)

        return np_abs(old_centers - centers)
Exemple #12
0
    def train_epoch(self, input_train, target_train):
        centers = self.centers
        old_centers = centers.copy()
        output_train = self.predict(input_train)

        for i, center in enumerate(centers):
            positions = argwhere(output_train[:, 0] == i)

            if not np_any(positions):
                continue

            class_data = take(input_train, positions, axis=0)
            centers[i, :] = (1 / len(class_data)) * np_sum(class_data, axis=0)

        return np_abs(old_centers - centers)
Exemple #13
0
def pHfromTATC(TA, TC, K1, K2, KW, KB, KF, KS, KP1, KP2, KP3, KSi, KNH3, KH2S,
               TB, TF, TS, TP, TSi, TNH3, TH2S):
    """Calculate pH from total alkalinity and dissolved inorganic carbon.

    This calculates pH from TA and TC using K1 and K2 by Newton's method.
    It tries to solve for the pH at which Residual = 0.
    The starting guess is pH = 8.
    Though it is coded for H on the total pH scale, for the pH values occuring
    in seawater (pH > 6) it will be equally valid on any pH scale (H terms
    negligible) as long as the K Constants are on that scale.

    Based on CalculatepHfromTATC, version 04.01, 10-13-96, by Ernie Lewis.
    SVH2007: Made this to accept vectors. It will continue iterating until all
    values in the vector are "abs(deltapH) < pHTol".
    """
    pHGuess = 8.0  # this is the first guess
    pH = full_like(TA, pHGuess)  # first guess for all samples
    deltapH = 1 + pHTol
    ln10 = log(10)
    while np_any(np_abs(deltapH) > pHTol):
        HCO3, CO3, BAlk, OH, PAlk, SiAlk, NH3Alk, H2SAlk, Hfree, HSO4, HF = \
            AlkParts(pH, TC,
                K1, K2, KW, KB, KF, KS, KP1, KP2, KP3, KSi, KNH3, KH2S,
                TB, TF, TS, TP, TSi, TNH3, TH2S)
        CAlk = HCO3 + 2 * CO3
        H = 10.0**-pH
        Denom = H**2 + K1 * H + K1 * K2
        Residual = (TA - CAlk - BAlk - OH - PAlk - SiAlk - NH3Alk - H2SAlk +
                    Hfree + HSO4 + HF)
        # Find slope dTA/dpH (this is not exact, but keeps important terms):
        Slope = ln10 * (TC * K1 * H *
                        (H**2 + K1 * K2 + 4 * H * K2) / Denom**2 + BAlk * H /
                        (KB + H) + OH + H)
        deltapH = Residual / Slope  # this is Newton's method
        # To keep the jump from being too big:
        while any(np_abs(deltapH) > 1):
            FF = np_abs(deltapH) > 1
            deltapH[FF] /= 2.0
        # The following logical means that each row stops updating once its
        # deltapH value is beneath the pHTol threshold, instead of continuing
        # to update ALL rows until they all meet the threshold.
        # This approach avoids the problem of reaching a different
        # answer for a given set of input conditions depending on how many
        # iterations the other input rows take to solve. // MPH
        F = np_abs(deltapH) > pHTol
        pH[F] += deltapH[F]
        # ^pH is on the same scale as K1 and K2 were calculated.
    return pH
Exemple #14
0
    def attack(self):
        '''
        Manage attacking ants.
        '''
        world = self.world
        # Isolate enemies and own ants which are at attackradius + 2.
        enemy_engageable = {}
        own_engageable = {}
        f = self.world.get_engageable
        for enemy in world.enemy_ants:
            tmp = f(enemy)
            if np_any(tmp):
                tmp = set([tuple(loc) for loc in tmp])
                enemy_engageable[enemy] = tmp
                for own in tmp:
                    try:
                        own_engageable[own].add(enemy)
                    except KeyError:
                        own_engageable[own] = set(enemy)
        if RUNS_LOCALLY:
            log.debug('# OWN ENGAGEABLE : %s' % own_engageable)
            log.debug('# ENEMY ENGAGEABLE : %s' % enemy_engageable)

        # BASIC, INTIAL STRATEGY (PROBABLY ONLY GOOD FOR ISOLATED ENEMIES)
        # Notably, it does not consider clusters of enemy ants, pretending
        # enemy ants are always isolated.

        attack_mask = world.attack_mask
        get_legal_moves = world.get_legal_moves
        for enemy, engageable in enemy_engageable.items():
            own_moves = {}
            enemy_moves = get_legal_moves(enemy)
            for own in engageable:
                own_moves[own] = {}
                # Here's the key-passage: find out how each move would score
                # relative to the opponent's one.
                for odest, odir in get_legal_moves(own):
                    for edest, edir in enemy_moves:
                        if odest in world.get_in_attackradius(edest):
                            try:
                                own_moves[own][odest, odir].append((edest,
                                                                    edir))
                            except KeyError:
                                own_moves[own][odest, odir] = [(edest, edir)]
            if RUNS_LOCALLY:
                log.debug('# OWN MOVES FOR ENEMY %s : %s' % (enemy, own_moves))
                overlay.show_dangers(own_moves)
Exemple #15
0
    def discrete_validation(self, matrix):
        """ Validate discrete matrix.

        Parameters
        ----------
        matrix : array-like
            Matrix for validation.

        Returns
        -------
        bool
            Got ``True`` all ``matrix`` discrete values are in
            `discrete_values` list and `False` otherwise.
        """
        if np_any((matrix != 0) & (matrix != 1)):
            raise ValueError("This network is descrete. This mean that you "
                             "can use data which contains 0 and 1 values")
Exemple #16
0
    def discrete_validation(self, matrix):
        """ Validate discrete matrix.

        Parameters
        ----------
        matrix : array-like
            Matrix for validation.

        Returns
        -------
        bool
            Got ``True`` all ``matrix`` discrete values are in
            `discrete_values` list and `False` otherwise.
        """
        if np_any((matrix != 0) & (matrix != 1)):
            raise ValueError("This network is descrete. This mean that you "
                             "can use data which contains 0 and 1 values")
Exemple #17
0
        def _gatherer(group,
                      trail,
                      xcol=None,
                      ycol=None,
                      xerr=None,
                      yerr=None,
                      **kargs):
            yerr = None
            xerr = None
            cols = group[0]._col_args(xcol=xcol,
                                      ycol=ycol,
                                      xerr=xerr,
                                      yerr=yerr,
                                      scalar=False)
            lookup = xcol is None and ycol is None
            xcol = cols["xcol"]

            if cols["has_xerr"]:
                xerr = cols["xerr"]
            else:
                xerr = None

            common_x = kargs.pop("common_x", True)

            results = group.type()
            results.metadata = group[0].metadata
            xbase = group[0].column(xcol)
            xtitle = group[0].column_headers[xcol]
            results.add_column(xbase, header=xtitle, setas="x")
            if cols["has_xerr"]:
                xerrdata = group[0].column(xerr)
                xerr_title = "Error in {}".format(xtitle)
                results.add_column(xerrdata, header=xerr_title, setas="d")
            for f in group:
                if lookup:
                    cols = f._col_args(scalar=False)
                    xcol = cols["xcol"]
                xdata = f.column(xcol)
                if np_any(xdata != xbase) and not common_x:
                    xtitle = group[0].column_headers[xcol]
                    results.add_column(xbase, header=xtitle, setas="x")
                    xbase = xdata
                    if cols["has_xerr"]:
                        xerr = cols["xerr"]
                        xerrdata = f.column(xerr)
                        xerr_title = "Error in {}".format(xtitle)
                        results.add_column(xerrdata,
                                           header=xerr_title,
                                           setas="d")
                for col, has_err, ecol, setcol, setecol in zip(
                    ["ycol", "zcol", "ucol", "vcol", "wcol"],
                    ["has_yerr", "has_zerr", "", "", ""],
                    ["yerr", "zerr", "", "", ""],
                        "yzuvw",
                        "ef...",
                ):
                    if len(cols[col]) == 0:
                        continue
                    data = f.column(cols[col])
                    for i in range(len(cols[col])):
                        title = "{}:{}".format(path.basename(f.filename),
                                               f.column_headers[cols[col][i]])
                        results.add_column(data[:, i],
                                           header=title,
                                           setas=setcol)
                    if has_err != "" and cols[has_err]:
                        err_data = f.column(cols[ecol])
                        for i in range(len(cols[ecol])):
                            title = "{}:{}".format(
                                path.basename(f.filename),
                                f.column_headers[cols[ecol][i]])
                            results.add_column(err_data[:, i],
                                               header=title,
                                               setas=setecol)
            return results
def compute_intersect_edges_sphere_np(verts_in, edges_in, sphere_loc, radius,
                                      result, gates):
    '''
        Calculate all intersections of a sphere with one edges mesh with NumPy and in case of none intersection returns closest point of line and over the sphere.
        Adapted from Marco13 answer in https://math.stackexchange.com/questions/1905533/
        segments are calculated from verts_in and edges_in (regular lists
        sphere_loc and radius as regular lists or tuples
        result as a [[], [], [], [], [], [], []] to append the data
        and gates as a boolean list to return:
            [mask: valid intersection,
            inter_a: the intersection nearer to the end point of the segment,
            inter_b: the intersection nearer to the start point of the segment,
            inter_a_in_segment: if A intersection is over the segment,
            inter_b_in_segment: if B intersection is over the segment,
            first_inter_in_segment: returns the first valid value between Int. A, Int. B and Closest point,
            inter_with_segment: returns true if there is any intersection in the segment
            all_inter: returns a flat list of all the intersections
            out_numpy: return NumPy arrays or regular lists]
    '''

    np_verts = array(verts_in)
    if not edges_in:
        edges_in = [[0, -1]]
    np_edges = array(edges_in)
    np_centers = array(sphere_loc)
    np_rad = array(radius)

    segment_orig = np_verts[np_edges[:, 0]]
    segment = np_verts[np_edges[:, 1]] - segment_orig
    segment_mag = np_norm(segment, axis=1)
    segment_dir = segment / segment_mag[:, newaxis]

    join_vect = np_centers[:, newaxis] - segment_orig
    join_vect_proy = np_sum(join_vect * segment_dir, axis=2)

    closest_point = segment_orig + join_vect_proy[:, :, newaxis] * segment_dir
    dif_v = closest_point - np_centers[:, newaxis, :]
    dist = np_norm(dif_v, axis=2)

    mask = dist > np_rad[:, newaxis]
    ang = arccos(dist / np_rad[:, newaxis])
    offset = np_rad[:, newaxis] * sin(ang)

    inter_a, inter_b = [], []
    inter_a_in_segment, inter_b_in_segment = [], []
    first_inter_in_segment, inter_with_segment = [], []
    all_inter = []
    any_inter = any(gates[5:8])

    if gates[1] or any_inter:
        inter_a = closest_point + segment_dir * offset[:, :, newaxis]
        inter_a[mask] = closest_point[mask]
    if gates[2] or any_inter:
        inter_b = closest_point - segment_dir * offset[:, :, newaxis]
        inter_b[mask] = closest_point[mask]

    if gates[3] or any_inter:
        inter_a_in_segment = np_all(
            [
                join_vect_proy + offset >= 0,
                join_vect_proy + offset <= segment_mag
            ],
            axis=0,
        )
    if gates[4] or any_inter:
        inter_b_in_segment = np_all(
            [
                join_vect_proy - offset >= 0,
                join_vect_proy - offset <= segment_mag
            ],
            axis=0,
        )

    if gates[5]:
        first_inter_in_segment = closest_point
        first_inter_in_segment[inter_b_in_segment] = inter_b[
            inter_b_in_segment]
        first_inter_in_segment[inter_a_in_segment] = inter_a[
            inter_a_in_segment]

    if gates[6]:
        inter_with_segment = np_any([inter_a_in_segment, inter_b_in_segment],
                                    axis=0)

    if gates[7]:
        all_inter = concatenate(
            (inter_a[inter_a_in_segment, :], inter_b[inter_b_in_segment, :]),
            axis=0)[newaxis, :, :]

    local_result = [
        invert(mask),
        inter_a,
        inter_b,
        inter_a_in_segment,
        inter_b_in_segment,
        first_inter_in_segment,
        inter_with_segment,
        all_inter,
    ]
    for i, res in enumerate(result):
        if gates[i]:
            if not gates[8]:

                for subres in local_result[i].tolist():
                    res.append(subres)

            else:
                res.append(local_result[i])
Exemple #19
0
def fixPosWLAN(len_wlan=None, wlan=None, wppdb=None, verb=False):
    """
    Returns the online fixed user location in lat/lon format.
    
    Parameters
    ----------
    len_wlan: int, mandatory
        Number of online visible WLAN APs.
    wlan: np.array, string list, mandatory
        Array of MAC/RSS for online visible APs.
        e.g. [['00:15:70:9E:91:60' '00:15:70:9E:91:61' '00:15:70:9E:91:62' '00:15:70:9E:6C:6C']
              ['-55' '-56' '-57' '-68']]. 
    verb: verbose mode option, default: False
        More debugging info if enabled(True).
    
    Returns
    -------
    posfix: np.array, float
        Final fixed location(lat, lon).
        e.g. [ 39.922942  116.472673 ]
    """
    interpart_offline = False; interpart_online = False

    # db query result: [ maxNI, keys:[ [keyaps:[], keycfps:(())], ... ] ].
    # maxNI=0 if no cluster found.
    maxNI,keys = wppdb.getBestClusters(macs=wlan[0])
    #maxNI,keys = [2, [
    #    [['00:21:91:1D:C0:D4', '00:19:E0:E1:76:A4', '00:25:86:4D:B4:C4'], 
    #        [[5634, 5634, 39.898019, 116.367113, '-83|-85|-89']] ],
    #    [['00:21:91:1D:C0:D4', '00:25:86:4D:B4:C4'],
    #        [[6161, 6161, 39.898307, 116.367233, '-90|-90']] ] ]]
    if maxNI == 0: # no intersection found
        wpplog.error('NO cluster found! Fingerprinting TERMINATED!')
        return []
    elif maxNI < CLUSTERKEYSIZE:
        # size of intersection set < offline key AP set size:4, 
        # offline keymacs/keyrsss (not online maxmacs/maxrsss) need to be cut down.
        interpart_offline = True
        if maxNI < len_wlan: #TODO: TBE.
            # size of intersection set < online AP set size(len_wlan) < CLUSTERKEYSIZE,
            # not only keymacs/keyrsss, but also maxmacs/maxrsss need to be cut down.
            interpart_online = True
        if verb: wpplog.debug('Partly[%d] matched cluster(s) found:' % maxNI)
    else: 
        if verb: wpplog.debug('Full matched cluster(s) found:')
    if verb: wpplog.debug('keys:\n%s' % keys)

    # Evaluation|sort of similarity between online FP & radio map FP.
    # fps_cand: [ min_spid1:[cid,spid,lat,lon,rsss], min_spid2, ... ]
    # keys: ID and key APs of matched cluster(s) with max intersect APs.
    all_pos_lenrss = []
    fps_cand = []; sums_cand = []
    for keyaps,keycfps in keys:
        if verb: wpplog.debug('keyaps:\n%s\nkeycfps:\n%s' % (keyaps, keycfps))
        # Fast fix when the ONLY 1 selected cid has ONLY 1 fp in 'cfps'.
        if len(keys)==1 and len(keycfps)==1:
            fps_cand = [ list(keycfps[0]) ]
            break
        pos_lenrss = (array(keycfps)[:,1:3].astype(float)).tolist()
        keyrsss = np_char_array(keycfps)[:,4].split('|') #4: column order in cfps.tbl
        keyrsss = array([ [float(rss) for rss in spid] for spid in keyrsss ])
        for idx,pos in enumerate(pos_lenrss):
            pos_lenrss[idx].append(len(keyrsss[idx]))
        all_pos_lenrss.extend(pos_lenrss)
        # Rearrange key MACs/RSSs in 'keyrsss' according to intersection set 'keyaps'.
        if interpart_offline:
            if interpart_online:
                wl = deepcopy(wlan) # mmacs->wl[0]; mrsss->wl[1]
                idxs_inters = [ idx for idx,mac in enumerate(wlan[0]) if mac in keyaps ]
                wl = wl[:,idxs_inters]
            else: wl = wlan
        else: wl = wlan
        idxs_taken = [ keyaps.index(x) for x in wl[0] ]
        keyrsss = keyrsss.take(idxs_taken, axis=1)
        mrsss = wl[1].astype(int)
        # Euclidean dist solving and sorting.
        sum_rss = np_sum( (mrsss-keyrsss)**2, axis=1 )
        fps_cand.extend( keycfps )
        sums_cand.extend( sum_rss )
        if verb: wpplog.debug('sum_rss:\n%s' % sum_rss)

    # Location estimation.
    if len(fps_cand) > 1:
        # KNN
        # lst_set_sums_cand: list format for set of sums_cand.
        # bound_dist: distance boundary for K-min distances.
        lst_set_sums_cand =  array(list(set(sums_cand)))
        idx_bound_dist = argsort(lst_set_sums_cand)[:KNN][-1]
        bound_dist = lst_set_sums_cand[idx_bound_dist]
        idx_sums_sort = argsort(sums_cand)

        sums_cand = array(sums_cand)
        fps_cand = array(fps_cand)

        sums_cand_sort = sums_cand[idx_sums_sort]
        idx_bound_fp = searchsorted(sums_cand_sort, bound_dist, 'right')
        idx_sums_sort_bound = idx_sums_sort[:idx_bound_fp]
        #idxs_kmin = argsort(min_sums)[:KNN]
        sorted_sums = sums_cand[idx_sums_sort_bound]
        sorted_fps = fps_cand[idx_sums_sort_bound]
        if verb: wpplog.debug('k-dists:\n%s\nk-locations:\n%s' % (sorted_sums, sorted_fps))
        # DKNN
        if sorted_sums[0]: 
            boundry = sorted_sums[0]*KWIN
        else: 
            if sorted_sums[1]:
                boundry = KWIN
                # What the hell are the following two lines doing here!
                #idx_zero_bound = searchsorted(sorted_sums, 0, side='right')
                #sorted_sums[:idx_zero_bound] = boundry / (idx_zero_bound + .5)
            else: boundry = 0
        idx_dkmin = searchsorted(sorted_sums, boundry, side='right')
        dknn_sums = sorted_sums[:idx_dkmin].tolist()
        dknn_fps = sorted_fps[:idx_dkmin]
        if verb: wpplog.debug('dk-dists: \n%s\ndk-locations: \n%s' % (dknn_sums, dknn_fps))
        # Weighted_AVG_DKNN.
        num_dknn_fps = len(dknn_fps)
        if  num_dknn_fps > 1:
            coors = dknn_fps[:,1:3].astype(float)
            num_keyaps = array([ rsss.count('|')+1 for rsss in dknn_fps[:,-2] ])
            # ww: weights of dknn weights.
            ww = np_abs(num_keyaps - len_wlan).tolist()
            #wpplog.debug(ww)
            if not np_all(ww):
                if np_any(ww):
                    ww_sort = np_sort(ww)
                    #wpplog.debug('ww_sort: %s' % ww_sort)
                    idx_dknn_sums_sort = searchsorted(ww_sort, 0, 'right')
                    #wpplog.debug('idx_dknn_sums_sort: %s' % idx_dknn_sums_sort)
                    ww_2ndbig = ww_sort[idx_dknn_sums_sort] 
                    w_zero = ww_2ndbig / (len(ww)*ww_2ndbig)
                else: w_zero = 1
                #for idx,sum in enumerate(ww):
                #    if not sum: ww[idx] = w_zero
                ww = [ w if w else w_zero for w in ww ]
            ws = array(ww) + dknn_sums
            weights = reciprocal(ws)
            if verb: wpplog.debug('coors:%s, weights:%s' % (coors, weights))
            posfix = average(coors, axis=0, weights=weights)
        else: posfix = array(dknn_fps[0][1:3]).astype(float)
        # ErrRange Estimation (more than 1 relevant clusters).
        idxs_clusters = idx_sums_sort_bound[:idx_dkmin]
        if len(idxs_clusters) == 1: 
            if maxNI == 1: poserr = 200
            else: poserr = 100
        else: 
            if verb: wpplog.debug('idxs_clusters: %s\nall_pos_lenrss: %s' % (idxs_clusters, all_pos_lenrss))
            #allposs_dknn = vstack(array(all_pos_lenrss, object)[idxs_clusters])
            allposs_dknn = array(all_pos_lenrss, object)[idxs_clusters]
            if verb: wpplog.debug('allposs_dknn: %s' % allposs_dknn)
            poserr = max( average([ dist_km(posfix[1], posfix[0], p[1], p[0])*1000 
                for p in allposs_dknn ]), 100 )
    else: 
        fps_cand = fps_cand[0][:-2]
        if verb: wpplog.debug('location:\n%s' % fps_cand)
        posfix = array(fps_cand[1:3]).astype(float)
        # ErrRange Estimation (only 1 relevant clusters).
        N_fp = len(keycfps)
        if N_fp == 1: 
            if maxNI == 1: poserr = 200
            else: poserr = 150
        else:
            if verb: 
                wpplog.debug('all_pos_lenrss: %s' % all_pos_lenrss)
                wpplog.debug('posfix: %s' % posfix)
            poserr = max( np_sum([ dist_km(posfix[1], posfix[0], p[1], p[0])*1000 
                for p in all_pos_lenrss ]) / (N_fp-1), 100 )
    ret = posfix.tolist()
    ret.append(poserr)

    return ret