Project: s41467-024-49957-9 | Function: find_min_loc (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Core optimization algorithm for finding optimal primer design regions (PDRs) within specified genomic coordinates, implementing greedy selection with randomization to balance exploration and exploitation while minimizing risk scores for automated primer placement

**KEY TERMS:** {
  "risk_arr": "genomic risk score array capturing undesired sequence features",
  "PRIMER_DESIGN_LEN": "40nt PDR length for primer candidate generation",
  "CHOICE_RATE": "0.3 parameter controlling greediness level in PDR selection",
  "score": "cumulative risk scores for all candidate PDR positions",
  "idx_k_lowest": "indices of k lowest-risk PDR candidates",
  "primer_start": "selected optimal starting position for PDR placement"
}

**CONTEXT CODE:** import logging
logger = logging.getLogger('main')

import numpy as np
import pandas as pd
import pickle
import random
import multiprocessing

from time import time
from numpy.random import rand, default_rng
from copy import deepcopy
from tqdm import tqdm
from math import floor

# imternal modules
import basic
import design
from msa_tools import Primer, expand_degenerate_sequence
from collections import defaultdict

# algorithmic parameters
PRIMER_DESIGN_LEN = 40 # length of primer design region [40]
UPPER_GC = 0.75 # extreme GC upper bond [0.75]
LOWER_GC = 0.25 # extreme GC lower bond [0.75]
LOW_COMPLEXITY = 0.4 # low complexity lower bond [0.4]
CHOICE_RATE = 0.3 # bottom CHOICE_RATE lowest risk primer design regions are choosen from candidate region
RISK_TH = 0.1 # top RISK_TH highest risk primer design regions are considered as loss

N_POOLS = 2 # number of primer pool (not to be changed)

def find_min_loc(risk_arr, start, stop, rng):
    '''
    find the next primer design region within start and stop.
    '''
    raise NotImplementedError("Function has been masked for testing purposes")


def generate_context(SOI):
    '''
    find a valid set of PDRs that cover the whole sequence of interest (SOI).
    '''
    risk_arr, start, stop, max_amp_len, min_amp_len, seed = SOI
    SOI_len = stop - start + 1
    rng = default_rng(seed)
    
    all_context_seq = [] # coordinates of all context sequences
    all_risk = []

    # generate the first pair of primer design region
    fp_start, fp_stop, fp_risk = find_min_loc(risk_arr, start, start+3*PRIMER_DESIGN_LEN-1, rng)
    rp_stop, rp_start, rp_risk = find_min_loc(risk_arr, fp_start+min_amp_len-PRIMER_DESIGN_LEN, fp_start+max_amp_len-1, rng)
    all_context_seq.append((fp_start, fp_stop, rp_stop, rp_start))
    all_risk.append((fp_risk, rp_risk))

    # generate the second pair of primer design region
    left_lim = max(fp_stop+1, rp_start+2*PRIMER_DESIGN_LEN-max_amp_len+1) # leave space for the next fP design region
    fp_start, fp_stop, fp_risk = find_min_loc(risk_arr, left_lim, rp_stop-1, rng)
    left_lim = max(fp_start+min_amp_len-PRIMER_DESIGN_LEN, rp_start+PRIMER_DESIGN_LEN+1)
    right_lim = fp_start+max_amp_len-1
    if right_lim > stop:
        raise ValueError('sequence provided is too short.')
    rp_stop, rp_start, rp_risk = find_min_loc(risk_arr, left_lim, right_lim, rng)
    all_context_seq.append((fp_start, fp_stop, rp_stop, rp_start))
    all_risk.append((fp_risk, rp_risk))

    # design the rest context sequences
    cs_id = 2 # id of the next context sequence to be designed (0-based)
    while True:
        # fp
        # all_context_seq[cs_id-2][3]: rp_start of the last last context sequence
        left_lim = max(all_context_seq[cs_id-2][3]+1, rp_start+2*PRIMER_DESIGN_LEN-max_amp_len+1)
        fp_start, fp_stop, fp_risk = find_min_loc(risk_arr, left_lim, rp_stop-1, rng)
        # rp
        left_lim = max(fp_start+min_amp_len-PRIMER_DESIGN_LEN, rp_start+PRIMER_DESIGN_LEN+1)
        right_lim = fp_start+max_amp_len-1
        if right_lim > stop:
            break
        rp_stop, rp_start, rp_risk = find_min_loc(risk_arr, left_lim, right_lim, rng)

        all_context_seq.append((fp_start, fp_stop, rp_stop, rp_start))
        all_risk.append((fp_risk, rp_risk))
        cs_id += 1

    all_context_seq = np.array(all_context_seq)
    all_risk = np.array(all_risk)
    all_risk_flatten = all_risk.flatten()
    k = int(len(all_risk_flatten) * (1-RISK_TH))

    cover_start = all_context_seq[0][1]+1
    cover_stop = all_context_seq[-1][2]-1
    coverage = (cover_stop-cover_start+1)/SOI_len

    loss = sum(np.partition(all_risk_flatten, k)[k:]**2)/(coverage**2)
    #loss = sum(all_risk_flatten[all_risk_flatten>=RISK_TH])
    return all_context_seq, all_risk, loss


def design_context_seq(config, deg: bool):
    '''
    PDR optimization. 
    Input:
        config: design configurations
    Output:
        all_plex_info
    '''
    ref_path = config['ref_path']
    max_amp_len = config['max_amp_len']
    w_gc = config['w_egc']
    w_complexity = config['w_lc']
    w_hits = config['w_ns']
    w_var = config['w_var']

    w_sensi = config['w_sensi']
    w_combi = config['w_combi']

    seed = config['seed']
    n_cpu = config['threads']
    iterMul = config['iterMul']

    if not deg:
        w_sensi = 0
        w_combi = 0
    
    # set random number generator
    rng_parent = default_rng(seed)
    
    with open(ref_path,  'rb') as f:
        olv_ref = pickle.load(f)

    seq_raw = olv_ref['seq'] # SNPs are capitalized in build()


Complete the function implementation replacing "raise NotImplementedError".