Instruction:
Write a Python 3 function for
generating the sub_codons_left dictionary of codon prefixes.

Response:
def generate_sub_codons_left(codons_dict):
    """Generate the sub_codons_left dictionary of codon prefixes.

    Parameters
    ----------
    codons_dict : dict
        Dictionary, keyed by the allowed 'amino acid' symbols with the values
        being lists of codons corresponding to the symbol.

    Returns
    -------
    sub_codons_left : dict
        Dictionary of the 1 and 2 nucleotide prefixes (read from 5') for
        each codon in an 'amino acid' grouping

    """
    sub_codons_left = {}
    for aa in codons_dict.keys():
        sub_codons_left[aa] = list(set([x[0] for x in codons_dict[aa]] + [x[:2] for x in codons_dict[aa]]))

    return sub_codons_left


Instruction:
Make a summary of the following Python 3 code
def generate_sub_codons_right(codons_dict):
    sub_codons_right = {}
    for aa in codons_dict.keys():
        sub_codons_right[aa] = list(set([x[-1] for x in codons_dict[aa]] + [x[-2:] for x in codons_dict[aa]]))

    return sub_codons_right

Response: Generate the sub_codons_right dictionary of codon suffixes.


Instruction:
Write a Python 3 function for
determining the type of a sequence.

Response:
def determine_seq_type(seq, aa_alphabet):
    """Determine the type of a sequence.

    Parameters
    ----------

    seq : str
        Sequence to be typed.
    aa_alphabet : str
        String of all characters recoginized as 'amino acids'. (i.e. the keys
        of codons_dict: aa_alphabet = ''.join(codons_dict.keys())  )

    Returns
    -------
    seq_type : str
        The type of sequence (ntseq, aaseq, regex, None) seq is.

    Example
    --------
    >>> determine_seq_type('TGTGCCAGCAGTTCCGAAGGGGCGGGAGGGCCCTCCCTGAGAGGTCATGAGCAGTTCTTC', aa_alphabet)
    'ntseq'
    >>> determine_seq_type('CSARDX[TV]GNX{0,}', aa_alphabet)
    'regex

    """

    if all([x in 'ACGTacgt' for x in seq]):
        return 'ntseq'
    elif all([x in aa_alphabet for x in seq]):
        return 'aaseq'
    elif all([x in aa_alphabet + '[]{}0123456789,']):
        return 'regex'


Instruction:
Can you implement a function in Python 3 that
calculates the steady state distribution of a 4 state markov transition matrix.

Response:
def calc_steady_state_dist(R):
    """Calculate the steady state dist of a 4 state markov transition matrix.

    Parameters
    ----------
    R : ndarray
        Markov transition matrix

    Returns
    -------
    p_ss : ndarray
        Steady state probability distribution

    """
    #Calc steady state distribution for a dinucleotide bias matrix

    w, v = np.linalg.eig(R)

    for i in range(4):
        if np.abs(w[i] - 1) < 1e-8:
            return np.real(v[:, i] / np.sum(v[:, i]))
    return -1


Instruction:
Write a Python 3 function for
generating a random insertion sequence of length ins_len from the distribution C_Rvd and CP_first_nt.

Response:
def rnd_ins_seq(ins_len, C_R, CP_first_nt):
    """Generate a random insertion nucleotide sequence of length ins_len.

    Draws the sequence identity (for a set length) from the distribution
    defined by the dinucleotide markov model of transition matrix R.

    Parameters
    ----------
    ins_len : int
        Length of nucleotide sequence to be inserted.
    C_R : ndarray
        (4, 4) array of the cumulative transition probabilities defined by the
        Markov transition matrix R
    CP_first_nt : ndarray
        (4,) array of the cumulative probabilities for the first inserted
        nucleotide

    Returns
    -------
    seq : str
        Randomly generated insertion sequence of length ins_len.

    Examples
    --------
    >>> rnd_ins_seq(7, CP_generative_model['C_Rvd'], CP_generative_model['C_first_nt_bias_insVD'])
    'GATGGAC'
    >>> rnd_ins_seq(7, CP_generative_model['C_Rvd'], CP_generative_model['C_first_nt_bias_insVD'])
    'ACCCCCG'
    >>> rnd_ins_seq(3, CP_generative_model['C_Rvd'], CP_generative_model['C_first_nt_bias_insVD'])
    'GCC'

    """
    nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
    num2nt = 'ACGT'

    if ins_len == 0:
        return ''

    seq = num2nt[CP_first_nt.searchsorted(np.random.random())]
    ins_len += -1

    while ins_len > 0:
        seq += num2nt[C_R[nt2num[seq[-1]], :].searchsorted(np.random.random())]
        ins_len += -1

    return seq


Instruction:
Write a Python 3 script for
generating a productive CDR3 sequence from a Monte Carlo draw of the model.

Response:
def gen_rnd_prod_CDR3(self, conserved_J_residues = 'FVW'):
        """Generate a productive CDR3 seq from a Monte Carlo draw of the model.

        Parameters
        ----------
        conserved_J_residues : str, optional
            Conserved amino acid residues defining the CDR3 on the J side (normally
            F, V, and/or W)

        Returns
        -------
        ntseq : str
            Productive CDR3 nucleotide sequence
        aaseq : str
            CDR3 amino acid sequence (aaseq = nt2aa(ntseq))
        V_choice : int
            Index of V allele chosen to generate the CDR3 seq
        J_choice : int
            Index of J allele chosen to generate the CDR3 seq

        """
        coding_pass = False

        while ~coding_pass:
            recomb_events = self.choose_random_recomb_events()
            V_seq = self.cutV_genomic_CDR3_segs[recomb_events['V']]

            #This both checks that the position of the conserved C is
            #identified and that the V isn't fully deleted out of the CDR3
            #region
            if len(V_seq) <= max(recomb_events['delV'], 0):
                continue
            D_seq = self.cutD_genomic_CDR3_segs[recomb_events['D']]
            J_seq = self.cutJ_genomic_CDR3_segs[recomb_events['J']]

            #We check that the D and J aren't deleted more than allowed. Note
            #the generative model really should reflect this structure already
            if len(D_seq) < (recomb_events['delDl'] + recomb_events['delDr']) or len(J_seq) < recomb_events['delJ']:
                continue

            V_seq = V_seq[:len(V_seq) - recomb_events['delV']]
            D_seq = D_seq[recomb_events['delDl']:len(D_seq)-recomb_events['delDr']]
            J_seq = J_seq[recomb_events['delJ']:]

            if (len(V_seq)+ len(D_seq) + len(J_seq) + recomb_events['insVD'] + recomb_events['insDJ']) % 3 != 0:
                continue

            insVD_seq = rnd_ins_seq(recomb_events['insVD'], self.C_Rvd, self.C_first_nt_bias_insVD)
            insDJ_seq = rnd_ins_seq(recomb_events['insDJ'], self.C_Rdj, self.C_first_nt_bias_insDJ)[::-1] #have to reverse the DJ seq

            #Translate to amino acid sequence, see if productive
            ntseq = V_seq + insVD_seq + D_seq + insDJ_seq + J_seq
            aaseq = nt2aa(ntseq)

            if '*' not in aaseq and aaseq[0]=='C' and aaseq[-1] in conserved_J_residues:
                return ntseq, aaseq, recomb_events['V'], recomb_events['J']


Instruction:
How would you implement a function in Python 3 that
samples the genomic model for the VDJ recombination events.

Response:
def choose_random_recomb_events(self):
        """Sample the genomic model for VDJ recombination events.

        Returns
        -------
        recomb_events : dict
            Dictionary of the VDJ recombination events. These are
            integers determining gene choice, deletions, and number of insertions.

        Example
        --------
        >>> sequence_generation.choose_random_recomb_events()
        {'D': 0, 'J': 13, 'V': 36, 'delDl': 2, 'delDr': 13, 'delJ': 10, 'delV': 5, 'insDJ': 6, 'insVD': 9}

        """

        recomb_events = {}
        recomb_events['V'] = self.CPV.searchsorted(np.random.random())

        #For 2D arrays make sure to take advantage of a mod expansion to find indicies
        DJ_choice = self.CPDJ.searchsorted(np.random.random())
        recomb_events['D'] = DJ_choice/self.num_J_genes
        recomb_events['J'] = DJ_choice % self.num_J_genes

        #Refer to the correct slices for the dependent distributions
        recomb_events['delV'] = self.given_V_CPdelV[recomb_events['V'], :].searchsorted(np.random.random())

        recomb_events['delJ'] = self.given_J_CPdelJ[recomb_events['J'], :].searchsorted(np.random.random())

        delDldelDr_choice = self.given_D_CPdelDldelDr[recomb_events['D'], :].searchsorted(np.random.random())

        recomb_events['delDl'] = delDldelDr_choice/self.num_delDr_poss
        recomb_events['delDr'] = delDldelDr_choice % self.num_delDr_poss

        recomb_events['insVD'] = self.CinsVD.searchsorted(np.random.random())
        recomb_events['insDJ'] = self.CinsDJ.searchsorted(np.random.random())

        return recomb_events


Instruction:
How would you code a function in Python 3 to
generate a productive CDR3 sequence from a Monte Carlo draw of the model.

Response:
def gen_rnd_prod_CDR3(self, conserved_J_residues = 'FVW'):
        """Generate a productive CDR3 seq from a Monte Carlo draw of the model.

        Parameters
        ----------
        conserved_J_residues : str, optional
            Conserved amino acid residues defining the CDR3 on the J side (normally
            F, V, and/or W)

        Returns
        -------
        ntseq : str
            Productive CDR3 nucleotide sequence
        aaseq : str
            CDR3 amino acid sequence (aaseq = nt2aa(ntseq))
        V_choice : int
            Index of V allele chosen to generate the CDR3 seq
        J_choice : int
            Index of J allele chosen to generate the CDR3 seq

        """

        coding_pass = False

        while ~coding_pass:
            recomb_events = self.choose_random_recomb_events()
            V_seq = self.cutV_genomic_CDR3_segs[recomb_events['V']]

            #This both checks that the position of the conserved C is
            #identified and that the V isn't fully deleted out of the CDR3
            #region
            if len(V_seq) <= max(recomb_events['delV'], 0):
                continue
            J_seq = self.cutJ_genomic_CDR3_segs[recomb_events['J']]

            #We check that J isn't deleted more than allowed. Note the
            #generative model really should reflect this structure already
            if len(J_seq) < recomb_events['delJ']:
                continue

            V_seq = V_seq[:len(V_seq) - recomb_events['delV']]
            J_seq = J_seq[recomb_events['delJ']:]

            if (len(V_seq)+len(J_seq) + recomb_events['insVJ']) % 3 != 0:
                continue

            insVJ_seq = rnd_ins_seq(recomb_events['insVJ'], self.C_Rvj, self.C_first_nt_bias_insVJ)

            #Translate to amino acid sequence, see if productive
            ntseq = V_seq + insVJ_seq + J_seq
            aaseq = nt2aa(ntseq)

            if '*' not in aaseq and aaseq[0]=='C' and aaseq[-1] in conserved_J_residues:
                return ntseq, aaseq, recomb_events['V'], recomb_events['J']


Instruction:
Write a Python 3 function that can
sample the genomic model for VDJ recombination events.

Response:
def choose_random_recomb_events(self):
        """Sample the genomic model for VDJ recombination events.

        Returns
        -------
        recomb_events : dict
            Dictionary of the VDJ recombination events. These are
            integers determining gene choice, deletions, and number of insertions.

        Example
        --------
        >>> sequence_generation.choose_random_recomb_events()
        {'J': 13, 'V': 36, 'delJ': 10, 'delV': 5, 'insVJ': 3}

        """

        recomb_events = {}

        #For 2D arrays make sure to take advantage of a mod expansion to find indicies
        VJ_choice = self.CPVJ.searchsorted(np.random.random())
        recomb_events['V'] = VJ_choice/self.num_J_genes
        recomb_events['J'] = VJ_choice % self.num_J_genes

        #Refer to the correct slices for the dependent distributions
        recomb_events['delV'] = self.given_V_CPdelV[recomb_events['V'], :].searchsorted(np.random.random())

        recomb_events['delJ'] = self.given_J_CPdelJ[recomb_events['J'], :].searchsorted(np.random.random())
        recomb_events['insVJ'] = self.CPinsVJ.searchsorted(np.random.random())

        return recomb_events


Instruction:
How would you code a function in Python 3 to
update the rates for a source

Response:
def update_rates(self):
        """
        Creates or updates rates for a source
        """
        source, created = RateSource.objects.get_or_create(name=self.get_source_name())
        source.base_currency = self.get_base_currency()
        source.save()

        for currency, value in six.iteritems(self.get_rates()):
            try:
                rate = Rate.objects.get(source=source, currency=currency)
            except Rate.DoesNotExist:
                rate = Rate(source=source, currency=currency)

            rate.value = value
            rate.save()


Instruction:
Can you generate the documentation for the following Python 3 function
def sample_gtf(data, D, k, likelihood='gaussian', prior='laplace',
                           lambda_hyperparams=None, lam_walk_stdev=0.01, lam0=1.,
                           dp_hyperparameter=None, w_hyperparameters=None,
                           iterations=7000, burn=2000, thin=10,
                           robust=False, empirical=False,
                           verbose=False):
    '''Generate samples from the generalized graph trend filtering distribution via a modified Swendsen-Wang slice sampling algorithm.
    Options for likelihood: gaussian, binomial, poisson. Options for prior: laplace, doublepareto.'''
    Dk = get_delta(D, k)
    dk_rows, dk_rowbreaks, dk_cols, dk_vals = decompose_delta(Dk)

    if likelihood == 'gaussian':
        y, w = data
    elif likelihood == 'binomial':
        trials, successes = data
    elif likelihood == 'poisson':
        obs = data
    else:
        raise Exception('Unknown likelihood type: {0}'.format(likelihood))

    if prior == 'laplace':
        if lambda_hyperparams == None:
            lambda_hyperparams = (1., 1.)
    elif prior == 'laplacegamma':
        if lambda_hyperparams == None:
            lambda_hyperparams = (1., 1.)
        if dp_hyperparameter == None:
            dp_hyperparameter = 1.
    elif prior == 'doublepareto' or prior == 'doublepareto2':
        if lambda_hyperparams == None:
            lambda_hyperparams = (1.0, 1.0)
        if dp_hyperparameter == None:
            dp_hyperparameter = 0.1
    elif prior == 'cauchy':
        if lambda_hyperparams == None:
            lambda_hyperparams = (1.0, 1.0)
    else:
        raise Exception('Unknown prior type: {0}.'.format(prior))

    if robust and w_hyperparameters is None:
        w_hyperparameters = (1., 1.)

    # Run the Gibbs sampler
    sample_size = (iterations - burn) / thin
    beta_samples = np.zeros((sample_size, D.shape[1]), dtype='double')
    lam_samples = np.zeros(sample_size, dtype='double')

    if likelihood == 'gaussian':
        if prior == 'laplace':
            gflbayes_gaussian_laplace(len(y), y, w,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'laplacegamma':
            if robust:
                gflbayes_gaussian_laplace_gamma_robust(len(y), y, w,
                                          dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                          lambda_hyperparams[0], lambda_hyperparams[1],
                                          dp_hyperparameter,
                                          w_hyperparameters[0], w_hyperparameters[1],
                                          iterations, burn, thin,
                                          double_matrix_to_c_pointer(beta_samples), lam_samples)
            else:
                gflbayes_gaussian_laplace_gamma(len(y), y, w,
                                          dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                          lambda_hyperparams[0], lambda_hyperparams[1],
                                          dp_hyperparameter,
                                          iterations, burn, thin,
                                          double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'doublepareto':
            gflbayes_gaussian_doublepareto(len(y), y, w,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      lam_walk_stdev, lam0, dp_hyperparameter,
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'doublepareto2':
            gflbayes_gaussian_doublepareto2(len(y), y, w,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      dp_hyperparameter,
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'cauchy':
            gflbayes_gaussian_cauchy(len(y), y, w,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      lam_walk_stdev, lam0,
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
    elif likelihood == 'binomial':
        if prior == 'laplace':
            gflbayes_binomial_laplace(len(trials), trials, successes,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'doublepareto':
            gflbayes_binomial_doublepareto(len(trials), trials, successes,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      lam_walk_stdev, lam0, dp_hyperparameter,
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'laplacegamma':
            if empirical:
                gflbayes_empirical_binomial_laplace_gamma(len(trials), trials, successes,
                                          dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                          lam0,
                                          iterations, burn, thin,
                                          double_matrix_to_c_pointer(beta_samples), lam_samples)
            else:
                gflbayes_binomial_laplace_gamma(len(trials), trials, successes,
                                          dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                          lambda_hyperparams[0], lambda_hyperparams[1],
                                          dp_hyperparameter,
                                          iterations, burn, thin,
                                          double_matrix_to_c_pointer(beta_samples), lam_samples)
    elif likelihood == 'poisson':
        if prior == 'laplace':
            gflbayes_poisson_laplace(len(obs), obs,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
        elif prior == 'doublepareto':
            gflbayes_poisson_doublepareto(len(obs), obs,
                                      dk_rows, dk_rowbreaks, dk_cols, dk_vals,
                                      lambda_hyperparams[0], lambda_hyperparams[1],
                                      lam_walk_stdev, lam0, dp_hyperparameter,
                                      iterations, burn, thin,
                                      double_matrix_to_c_pointer(beta_samples), lam_samples)
    else:
        raise Exception('Unknown likelihood type: {0}'.format(likelihood))

    return (beta_samples,lam_samples)

Response: Generate samples from a generalized graph trend filtering distribution via a modified Swendsen - Wang slice sampling algorithm.


Instruction:
Explain what the following Python 3 code does
def compute_regex_CDR3_template_pgen(self, regex_seq, V_usage_mask_in = None, J_usage_mask_in = None, print_warnings = True, raise_overload_warning = True):

        V_usage_mask, J_usage_mask = self.format_usage_masks(V_usage_mask_in, J_usage_mask_in, print_warnings)

        CDR3_seqs = self.list_seqs_from_regex(regex_seq, print_warnings, raise_overload_warning)

        pgen = 0
        for  CDR3_seq in CDR3_seqs:
            if len(CDR3_seq) == 0:
                continue
            pgen += self.compute_CDR3_pgen(CDR3_seq, V_usage_mask, J_usage_mask)

        return pgen

Response: This function calculates the Pgen for all sequences that are consistent with a regular expression.


Instruction:
Make a summary of the following Python 3 code
def compute_aa_CDR3_pgen(self, CDR3_seq, V_usage_mask_in = None, J_usage_mask_in = None, print_warnings = True):
        if len(CDR3_seq) == 0:
            return  0
        for aa in CDR3_seq:
            if aa not in self.codons_dict.keys():
                #Check to make sure all symbols are accounted for
                if print_warnings:
                    print 'Invalid amino acid CDR3 sequence --- unfamiliar symbol: ' + aa
                return 0

        V_usage_mask, J_usage_mask = self.format_usage_masks(V_usage_mask_in, J_usage_mask_in, print_warnings)

        return self.compute_CDR3_pgen(CDR3_seq, V_usage_mask, J_usage_mask)

Response: Compute the Pgen for the amino acid sequence CDR3_seq.


Instruction:
Write a Python 3 script to
compute Pgen of all seqs hamming dist 1 (in amino acids) from CDR3_seq. Please note that this function will list out all the sequences that are hamming distance 1 from the base sequence and then calculate the Pgen of each sequence in succession. THIS CAN BE SLOW as it computes Pgen for L+1 sequences where L = len(CDR3_seq). (Examples are TCRB sequences/model) Parameters ---------- CDR3_seq : str CDR3 sequence composed of amino acids (ONLY the standard amino acids). Pgens for all sequences of hamming distance 1 (in amino acid sequence) are summed. V_usage_mask_in : str or list An object to indicate which V alleles should be considered. The default input is None which returns the list of all productive V alleles. J_usage_mask_in : str or list An object to indicate which J alleles should be considered. The default input is None which returns the list of all productive J alleles. print_warnings : bool Determines whether warnings are printed or not. Default ON. Returns ------- pgen : float The sum of generation probabilities (Pgens) of the sequences at most hamming distance 1 (in amino acids) from CDR3_seq.

Response:
def compute_hamming_dist_1_pgen(self, CDR3_seq, V_usage_mask_in = None, J_usage_mask_in = None, print_warnings = True):
        """Compute Pgen of all seqs hamming dist 1 (in amino acids) from CDR3_seq.

        Please note that this function will list out all the
        sequences that are hamming distance 1 from the base sequence and then
        calculate the Pgen of each sequence in succession. THIS CAN BE SLOW
        as it computes Pgen for L+1 sequences where L = len(CDR3_seq). (Examples
        are TCRB sequences/model)

        Parameters
        ----------
        CDR3_seq : str
            CDR3 sequence composed of amino acids (ONLY the standard amino acids).
            Pgens for all sequences of hamming distance 1 (in amino acid sequence)
            are summed.
        V_usage_mask_in : str or list
            An object to indicate which V alleles should be considered. The default
            input is None which returns the list of all productive V alleles.
        J_usage_mask_in : str or list
            An object to indicate which J alleles should be considered. The default
            input is None which returns the list of all productive J alleles.
        print_warnings : bool
            Determines whether warnings are printed or not. Default ON.

        Returns
        -------
        pgen : float
            The sum of generation probabilities (Pgens) of the sequences at most
            hamming distance 1 (in amino acids) from CDR3_seq.

        """

        #make sure that the symbol X is defined as the fully undetermined amino acid:
        #X ~ ACDEFGHIKLMNPQRSTVWY

        V_usage_mask, J_usage_mask = self.format_usage_masks(V_usage_mask_in, J_usage_mask_in, print_warnings)

        if len(CDR3_seq) == 0:
            return  0
        for aa in CDR3_seq:
            if aa not in 'ACDEFGHIKLMNPQRSTVWY':
                #Check to make sure all symbols are accounted for
                if print_warnings:
                    print 'Invalid amino acid CDR3 sequence --- unfamiliar symbol: ' + aa
                return 0
        tot_pgen = 0
        for i in range(len(CDR3_seq)):
            tot_pgen += self.compute_CDR3_pgen(CDR3_seq[:i] + 'X' + CDR3_seq[i+1:], V_usage_mask, J_usage_mask)
        tot_pgen += -(len(CDR3_seq) - 1)*self.compute_CDR3_pgen(CDR3_seq, V_usage_mask, J_usage_mask)
        return tot_pgen


Instruction:
Write a Python 3 function that can
compute the Pgen for the inframe nucleotide sequence CDR3_ntseq.

Response:
def compute_nt_CDR3_pgen(self, CDR3_ntseq, V_usage_mask_in = None, J_usage_mask_in = None, print_warnings = True):
        """Compute Pgen for the inframe nucleotide sequence CDR3_ntseq.

        Conditioned on the V genes/alleles indicated in V_usage_mask_in and the
        J genes/alleles in J_usage_mask_in. (Examples are TCRB sequences/model)

        Parameters
        ----------
        CDR3_ntseq : str
            Inframe nucleotide sequence composed of ONLY A, C, G, or T (either
            uppercase or lowercase).
        V_usage_mask_in : str or list
            An object to indicate which V alleles should be considered. The default
            input is None which returns the list of all productive V alleles.
        J_usage_mask_in : str or list
            An object to indicate which J alleles should be considered. The default
            input is None which returns the list of all productive J alleles.
        print_warnings : bool
            Determines whether warnings are printed or not. Default ON.

        Returns
        -------
        pgen : float64
            The generation probability (Pgen) of the sequence

        Examples
        --------
        >>> generation_probability.compute_nt_CDR3_pgen('TGTGCCTGGAGTGTAGCTCCGGACAGGGGTGGCTACACCTTC')
        3.2674893012379071e-12
        >>> generation_probability.compute_nt_CDR3_pgen('TGTGCCTGGAGTGTAGCTCCGGACAGGGGTGGCTACACCTTC', 'TRBV30*01', 'TRBJ1-2*01')
        2.3986503758867323e-12

        """

        if not len(CDR3_ntseq)%3 == 0:
            #Make sure sequence is inframe
            if print_warnings:
                print 'Invalid nucleotide CDR3 sequence --- out of frame sequence'
            return 0
        elif len(CDR3_ntseq) == 0:
            return 0
        else:
            for nt in CDR3_ntseq:
                if nt not in 'ACGTacgt':
                    if print_warnings:
                        print 'Invalid nucleotide CDR3 sequence --- unfamiliar nucleotide: ' + nt
                    return 0

        V_usage_mask, J_usage_mask = self.format_usage_masks(V_usage_mask_in, J_usage_mask_in, print_warnings)

        return self.compute_CDR3_pgen(nt2codon_rep(CDR3_ntseq), V_usage_mask, J_usage_mask)


Instruction:
Can you create a Python 3 function that
formats the usage masks into lists of indices.

Response:
def format_usage_masks(self, V_usage_mask_in, J_usage_mask_in, print_warnings = True):
        """Format raw usage masks into lists of indices.

        Usage masks allows the Pgen computation to be conditioned on the V and J
        gene/allele identities. The inputted masks are lists of strings, or a
        single string, of the names of the genes or alleles to be conditioned on.
        The default mask includes all productive V or J genes.

        Parameters
        ----------
        V_usage_mask_in : str or list
            An object to indicate which V alleles should be considered. The default
            input is None which returns the list of all productive V alleles.
        J_usage_mask_in : str or list
            An object to indicate which J alleles should be considered. The default
            input is None which returns the list of all productive J alleles.
        print_warnings : bool
            Determines whether warnings are printed or not. Default ON.

        Returns
        -------
        V_usage_mask : list of integers
            Indices of the V alleles to be considered in the Pgen computation
        J_usage_mask : list of integers
            Indices of the J alleles to be considered in the Pgen computation

        Examples
        --------
        >>> generation_probability.format_usage_masks('TRBV27*01','TRBJ1-1*01')
        ([34], [0])
        >>> generation_probability.format_usage_masks('TRBV27*01', '')
        ([34], [0, 1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13])
        >>> generation_probability.format_usage_masks(['TRBV27*01', 'TRBV13*01'], 'TRBJ1-1*01')
        ([34, 18], [0])

        """
        #Format the V usage mask
        if V_usage_mask_in is None: #Default case, use all productive V genes with non-zero probability
            #V_usage_mask = [v for v, V in enumerate(ppp['cutV_genomic_CDR3_segs']) if len(V) > 0]
            V_usage_mask = self.d_V_usage_mask
        elif isinstance(V_usage_mask_in, list):
            e_V_usage_mask = set()
            for v in V_usage_mask_in:
                try:
                    e_V_usage_mask = e_V_usage_mask.union(self.V_mask_mapping[v])
                except KeyError:
                    if print_warnings:
                        print 'Unfamiliar V gene/allele: ' + v
                    pass
            if len(e_V_usage_mask) == 0:
                if print_warnings:
                    print 'No recognized V genes/alleles. Using default V_usage_mask'
                V_usage_mask = self.d_V_usage_mask
            else:
                V_usage_mask = list(e_V_usage_mask)
        else:
            try:
                V_usage_mask = self.V_mask_mapping[V_usage_mask_in]
            except KeyError:
                #Do raise error here as the mask will be empty
                if print_warnings:
                    print 'Unfamiliar V usage mask: ' + str(V_usage_mask_in) + ', please check the allowed V alleles. Using default V_usage_mask'
                V_usage_mask = self.d_V_usage_mask

        #Format the J usage mask
        if J_usage_mask_in is None: #Default case, use all productive J genes with non-zero probability
            #J_usage_mask = [j for j, J in enumerate(ppp['cutJ_genomic_CDR3_segs']) if len(J) > 0]
            J_usage_mask = self.d_J_usage_mask
        elif isinstance(J_usage_mask_in, list):
            e_J_usage_mask = set()
            for j in J_usage_mask_in:
                try:
                    e_J_usage_mask = e_J_usage_mask.union(self.J_mask_mapping[j])
                except KeyError:
                    if print_warnings:
                        print 'Unfamiliar J gene/allele: ' + j
                    pass
            if len(e_J_usage_mask) == 0:
                if print_warnings:
                    print 'No recognized J genes/alleles. Using default J_usage_mask'
                J_usage_mask = self.d_J_usage_mask
            else:
                J_usage_mask = list(e_J_usage_mask)
        else:
            try:
                J_usage_mask = self.J_mask_mapping[J_usage_mask_in]
            except KeyError:
                #Do raise error here as the mask will be empty
                if print_warnings:
                    print 'Unfamiliar J usage mask: ' + str(J_usage_mask_in) + ', please check the allowed J alleles. Using default J_usage_mask'
                J_usage_mask = self.d_J_usage_mask

        return V_usage_mask, J_usage_mask


Instruction:
Can you generate the documentation for the following Python 3 function
def list_seqs_from_regex(self, regex_seq, print_warnings = True, raise_overload_warning = True):

        aa_symbols = ''.join(self.codons_dict)

        default_max_reps = 40

        #Check to make sure that expression is of the right form/symbols

        #Identify bracket expressions
        bracket_ex = [x for x in re.findall('\[[' + aa_symbols + ']*?\]|\{\d+,{0,1}\d*\}', regex_seq)]

        split_seq  = re.split('\[[' + aa_symbols + ']*?\]|\{\d+,{0,1}\d*\}', regex_seq)
        #Check that all remaining characters are in the codon dict
        for aa in ''.join(split_seq):
            if aa not in aa_symbols:
                if print_warnings:
                    print 'Unfamiliar symbol representing a codon:' + aa + ' --- check codon dictionary or the regex syntax'
                return []

        regex_list = [split_seq[i/2] if i%2 == 0 else bracket_ex[i/2] for i in range(len(bracket_ex) + len(split_seq)) if not (i%2 == 0 and len(split_seq[i/2]) ==  0)]

        max_num_seqs = 1
        for l, ex in enumerate(regex_list[::-1]):
            i = len(regex_list) - l - 1
            if ex[0] == '[': #bracket expression
                #check characters
                for aa in ex.strip('[]'):
                    if aa not in aa_symbols:
                        if print_warnings:
                            print 'Unfamiliar symbol representing a codon:' + aa + ' --- check codon dictionary'
                        return []
                max_num_seqs *= len(ex) - 2
            elif ex[0] == '{': #curly bracket
                if i == 0:
                    if print_warnings:
                        print "Can't have {} expression at start of sequence"
                    return []
                elif isinstance(regex_list[i-1], list):
                    if print_warnings:
                        print "Two {} expressions in a row is not supported"
                    return []
                elif regex_list[i-1][0] == '[':
                    syms = regex_list[i-1].strip('[]')
                    regex_list[i-1] = ''
                else:
                    syms = regex_list[i-1][-1]
                    regex_list[i-1] = regex_list[i-1][:-1]
                if ',' not in ex:
                    new_expression = [int(ex.strip('{}')), int(ex.strip('{}')), syms]
                    max_num_seqs *= len(syms)**new_expression[0]
                else:
                    try:
                        new_expression = [int(ex.strip('{}').split(',')[0]), int(ex.strip('{}').split(',')[1]), syms]
                    except ValueError: #No max limit --- use default
                        new_expression = [int(ex.strip('{}').split(',')[0]), default_max_reps, syms]
                    if new_expression[0] > new_expression[1]:
                        if print_warnings:
                            print 'Check regex syntax --- should be {min,max}'
                        return []
                    max_num_seqs *= sum([len(syms)**n for n in range(new_expression[0], new_expression[1]+1)])/len(syms)
                #print new_expression
                regex_list[i] = new_expression

        if max_num_seqs > 10000 and raise_overload_warning:
            if print_warnings:
                answer = raw_input('Warning large number of sequences (estimated ' + str(max_num_seqs) + ' seqs) match the regular expression. Possible memory and time issues. Continue? (y/n)')
                if not answer == 'y':
                    print 'Canceling...'
                    return []
            else:
                return []
        #print regex_list
        CDR3_seqs = ['']
        for l, ex in enumerate(regex_list[::-1]):
            i = len(regex_list) - l - 1
            if isinstance(ex, list): #curly bracket case
                c_seqs = ['']
                f_seqs = []
                for j in range(ex[1] + 1):
                    if j in range(ex[0], ex[1]+1):
                        f_seqs += c_seqs
                    c_seqs = [aa + c_seq for aa in ex[2] for c_seq in c_seqs]
                CDR3_seqs = [f_seq + CDR3_seq for f_seq in f_seqs for CDR3_seq in CDR3_seqs]
            elif len(ex) == 0:
                pass
            elif ex[0] == '[': #square bracket case
                CDR3_seqs = [aa + CDR3_seq for aa in ex.strip('[]') for CDR3_seq in CDR3_seqs]
            else:
                CDR3_seqs = [ex + CDR3_seq for CDR3_seq in CDR3_seqs]

        return list(set(CDR3_seqs))

Response: This function parses a limited regular expression vocabulary and lists all the sequences that match the regular expression.


Instruction:
Can you tell what is the following Python 3 function doing
def max_nt_to_aa_alignment_left(self, CDR3_seq, ntseq):

        max_alignment = 0
        if len(ntseq) == 0:
            return 0
        aa_aligned = True
        while aa_aligned:
            if ntseq[max_alignment:max_alignment+3] in self.codons_dict[CDR3_seq[max_alignment/3]]:
                max_alignment += 3
                if max_alignment/3 == len(CDR3_seq):
                    return max_alignment
            else:
                break
                aa_aligned = False
        last_codon = ntseq[max_alignment:max_alignment+3]
        codon_frag = ''
        for nt in last_codon:
            codon_frag += nt
            if codon_frag in self.sub_codons_left[CDR3_seq[max_alignment/3]]:
                max_alignment += 1
            else:
                break
        return max_alignment

Response: Find maximum match between CDR3_seq and ntseq from the left.


Instruction:
Create a Python 3 function for
finding maximum match between CDR3_seq and ntseq from the right. Returns the length of the maximum match between CDR3_seq and ntseq.

Response:
def max_nt_to_aa_alignment_right(self, CDR3_seq, ntseq):
        """Find maximum match between CDR3_seq and ntseq from the right.

        This function returns the length of the maximum length nucleotide
        subsequence of ntseq contiguous from the right (or 3' end) that is
        consistent with the 'amino acid' sequence CDR3_seq

        Parameters
        ----------
        CDR3_seq : str
            CDR3 sequence composed of 'amino acids' (single character symbols
            each corresponding to a collection of codons as given by codons_dict).
        ntseq : str
            Genomic (J locus) nucleotide sequence to match.

        Returns
        -------
        max_alignment : int
            Maximum length (in nucleotides) nucleotide sequence that matches the
            CDR3 'amino acid' sequence.

        Example
        --------
        >>> generation_probability.max_nt_to_aa_alignment_right('CASSSEGAGGPSLRGHEQFF', 'TTCATGAACACTGAAGCTTTCTTT')
        6

        """
        r_CDR3_seq = CDR3_seq[::-1] #reverse CDR3_seq
        r_ntseq = ntseq[::-1] #reverse ntseq
        max_alignment = 0
        if len(ntseq) == 0:
            return 0
        aa_aligned = True
        while aa_aligned:
            if r_ntseq[max_alignment:max_alignment+3][::-1] in self.codons_dict[r_CDR3_seq[max_alignment/3]]:
                max_alignment += 3
                if max_alignment/3 == len(CDR3_seq):
                    return max_alignment
            else:
                break
                aa_aligned = False
        r_last_codon = r_ntseq[max_alignment:max_alignment+3]
        codon_frag = ''
        for nt in r_last_codon:
            codon_frag = nt + codon_frag
            if codon_frag in self.sub_codons_right[r_CDR3_seq[max_alignment/3]]:
                max_alignment += 1
            else:
                break
        return max_alignment


Instruction:
Implement a function in Python 3 to
compute the Pgen for a given amino acid sequence and V_usage_mask and J_usage_mask.

Response:
def compute_CDR3_pgen(self, CDR3_seq, V_usage_mask, J_usage_mask):
        """Compute Pgen for CDR3 'amino acid' sequence CDR3_seq from VDJ model.

        Conditioned on the already formatted V genes/alleles indicated in
        V_usage_mask and the J genes/alleles in J_usage_mask.
        (Examples are TCRB sequences/model)

        Parameters
        ----------
        CDR3_seq : str
            CDR3 sequence composed of 'amino acids' (single character symbols
            each corresponding to a collection of codons as given by codons_dict).
        V_usage_mask : list
            Indices of the V alleles to be considered in the Pgen computation
        J_usage_mask : list
            Indices of the J alleles to be considered in the Pgen computation

        Returns
        -------
        pgen : float
            The generation probability (Pgen) of the sequence

        Examples
        --------
        >>> compute_CDR3_pgen('CAWSVAPDRGGYTF', ppp, [42], [1])
        1.203646865765782e-10
        >>> compute_CDR3_pgen(nt2codon_rep('TGTGCCTGGAGTGTAGCTCCGGACAGGGGTGGCTACACCTTC'), ppp, [42], [1])
        2.3986503758867323e-12
        >>> compute_CDR3_pgen('\xbb\x96\xab\xb8\x8e\xb6\xa5\x92\xa8\xba\x9a\x93\x94\x9f', ppp, [42], [1])
        2.3986503758867323e-12

        """

        #Genomic V alignment/matching (contribution from P(V, delV)), return Pi_V
        Pi_V, max_V_align = self.compute_Pi_V(CDR3_seq, V_usage_mask)

        #Include VD insertions (Rvd and PinsVD) to get the total contribution from the left (3') side. Return Pi_L
        Pi_L = self.compute_Pi_L(CDR3_seq, Pi_V, max_V_align)

        #Genomic J alignment/matching (contribution from P(D, J, delJ)), return Pi_J_given_D
        Pi_J_given_D, max_J_align = self.compute_Pi_J_given_D(CDR3_seq, J_usage_mask)

        #Include DJ insertions (Rdj and PinsDJ), return Pi_JinsDJ_given_D
        Pi_JinsDJ_given_D = self.compute_Pi_JinsDJ_given_D(CDR3_seq, Pi_J_given_D, max_J_align)

        #Include D genomic contribution (P(delDl, delDr | D)) to complete the contribution from the right (5') side. Return Pi_R
        Pi_R = self.compute_Pi_R(CDR3_seq, Pi_JinsDJ_given_D)

        pgen = 0

        #zip Pi_L and Pi_R together to get total pgen
        for pos in range(len(CDR3_seq)*3 - 1):
            pgen += np.dot(Pi_L[:, pos], Pi_R[:, pos+1])

        return pgen


Instruction:
How would you explain what the following Python 3 function does
def compute_Pi_V(self, CDR3_seq, V_usage_mask):
        #Note, the cutV_genomic_CDR3_segs INCLUDE the palindromic insertions and thus are max_palindrome nts longer than the template.
        #furthermore, the genomic sequence should be pruned to start at the conserved C

        Pi_V = np.zeros((4, len(CDR3_seq)*3)) #Holds the aggregate weight for each nt possiblity and position
        alignment_lengths = []
        for V_in in V_usage_mask:
            try:
                cutV_gen_seg = self.cutV_genomic_CDR3_segs[V_in]
            except IndexError:
                print 'Check provided V usage mask. Contains indicies out of allowed range.'
                continue
            current_alignment_length = self.max_nt_to_aa_alignment_left(CDR3_seq, cutV_gen_seg)
            alignment_lengths += [current_alignment_length]
            current_Pi_V = np.zeros((4, len(CDR3_seq)*3))

            if current_alignment_length > 0:
                #For first and last nt in a codon use PVdelV_nt_pos_vec
                current_Pi_V[:, :current_alignment_length] = self.PVdelV_nt_pos_vec[V_in][:, :current_alignment_length]
                for pos in range(1, current_alignment_length, 3): #for middle nt use PVdelV_2nd_nt_pos_per_aa_vec
                    current_Pi_V[:, pos] = self.PVdelV_2nd_nt_pos_per_aa_vec[V_in][CDR3_seq[pos/3]][:, pos]
                Pi_V[:, :current_alignment_length] += current_Pi_V[:, :current_alignment_length]

        return Pi_V, max(alignment_lengths)

Response: This function computes the Pi array corresponding to the V genomic nucleotide sequence and the V_usage_mask. This function computes the Pi array corresponding to the V genomic nucleotide sequence and the V_usage_mask.


Instruction:
Can you generate the documentation for the following Python 3 function
def compute_Pi_J_given_D(self, CDR3_seq, J_usage_mask):

        #Note, the cutJ_genomic_CDR3_segs INCLUDE the palindromic insertions and thus are max_palindrome nts longer than the template.
        #furthermore, the genomic sequence should be pruned to start at a conserved region on the J side
        num_D_genes = self.PD_given_J.shape[0]
        Pi_J_given_D = [np.zeros((4, len(CDR3_seq)*3)) for i in range(num_D_genes)] #Holds the aggregate weight for each nt possiblity and position
        alignment_lengths = []
        for J_in in J_usage_mask:
            try:
                cutJ_gen_seg = self.cutJ_genomic_CDR3_segs[J_in]
            except IndexError:
                print 'Check provided V usage mask. Contains indicies out of allowed range.'
                continue
            current_alignment_length = self.max_nt_to_aa_alignment_right(CDR3_seq, cutJ_gen_seg)
            alignment_lengths += [current_alignment_length]
            current_Pi_J = np.zeros((4, len(CDR3_seq)*3))

            if current_alignment_length > 0:
                #For first and last nt in a codon use PJdelJ_nt_pos_vec
                current_Pi_J[:, -current_alignment_length:] = self.PJdelJ_nt_pos_vec[J_in][:, -current_alignment_length:]
                for pos in range(-2, -current_alignment_length-1, -3): #for middle nt use PJdelJ_2nd_nt_pos_per_aa_vec
                    current_Pi_J[:, pos] = self.PJdelJ_2nd_nt_pos_per_aa_vec[J_in][CDR3_seq[pos/3]][:, pos]

            for D_in, pd_given_j in enumerate(self.PD_given_J[:, J_in]):
                Pi_J_given_D[D_in][:, -current_alignment_length:] += pd_given_j*current_Pi_J[:, -current_alignment_length:]

        return Pi_J_given_D, max(alignment_lengths)

Response: This function computes the Pi_J given the D and J_usage_mask. The method is used to compute the Pi_J given the D and J_usage_mask.


Instruction:
Here you have a function in Python 3, explain what it does
def compute_Pi_R(self, CDR3_seq, Pi_JinsDJ_given_D):

        #Need to consider all D alignments from all possible positions and right deletions.
        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}

        #n_aaseq = [aa_dict[aa] for aa in CDR3_seq]
        Pi_R = np.zeros((4, len(CDR3_seq)*3))
        min_pos = -len(CDR3_seq)*3

        num_dell_pos, num_delr_pos, num_D_genes = self.PdelDldelDr_given_D.shape

        for D_in, cutD_gen_seg  in enumerate(self.cutD_genomic_CDR3_segs):
            l_D_seg = len(cutD_gen_seg)

            #start position is first nt in a codon
            for init_pos in range(-1,-len(CDR3_seq)*3-1,-3):
                Pi_R[:, init_pos] += Pi_JinsDJ_given_D[D_in][:, init_pos]*self.zeroD_given_D[D_in]
                second_pos_dict = {'A': np.zeros(4), 'C': np.zeros(4), 'G': np.zeros(4), 'T': np.zeros(4)}
                codon_prefix_dict = {}

                for last_nt in 'ACGT':
                    for second_nt in 'ACGT':
                        codon_prefix_dict[last_nt + second_nt] = np.zeros(4)
                        #for first_nt in ['ACGT'[nt] for nt in range(4) if Pi_JinsDJ_given_D[D_in][nt, init_pos] > 0]:
                        for first_nt in 'ACGT':
                            if last_nt + second_nt + first_nt in self.codons_dict[CDR3_seq[init_pos/3]]: #possible allowed codon
                                second_pos_dict[second_nt][nt2num[last_nt]] += Pi_JinsDJ_given_D[D_in][nt2num[first_nt], init_pos] #base weight for middle pos nt
                                codon_prefix_dict[last_nt + second_nt][0] += Pi_JinsDJ_given_D[D_in][nt2num[first_nt], init_pos] #base weight for last pos nt
                for nt1 in 'ACGT':
                    if np.sum(second_pos_dict[nt1]) == 0:
                        second_pos_dict.pop(nt1, None)
                    for nt2 in 'ACGT':
                        if np.sum(codon_prefix_dict[nt1+nt2])== 0:
                            codon_prefix_dict.pop(nt1+nt2, None)

    #            if len(second_pos_dict)> 0:
    #                print second_pos_dict
    #                return -1

                for delDr in range(num_delr_pos):
                    if self.min_delDl_given_DdelDr[D_in][delDr] == -1: # P(delDr | D) = 0 for this delDr --> move to next
                        continue
                    #Check if first nt from the D segment is okay
                    if cutD_gen_seg[l_D_seg - delDr - 1] in second_pos_dict.keys():
                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if l_D_seg - delDr - 1 <= self.max_delDl_given_DdelDr[D_in][delDr]:
                            Pi_R[:, init_pos - 1] += self.PdelDldelDr_given_D[l_D_seg - delDr - 1, delDr, D_in]*second_pos_dict[cutD_gen_seg[l_D_seg - delDr - 1]]
                    else:
                        continue #not okay, reject the alignment

                    #Check if the second nt from the D segment is okay
                    if cutD_gen_seg[l_D_seg - delDr - 2:l_D_seg - delDr] in codon_prefix_dict.keys():
                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if l_D_seg - delDr - 2 <= self.max_delDl_given_DdelDr[D_in][delDr]:
                            Pi_R[0, init_pos - 2] += self.PdelDldelDr_given_D[l_D_seg - delDr - 2, delDr, D_in]*codon_prefix_dict[cutD_gen_seg[l_D_seg - delDr - 2:l_D_seg - delDr]][0]
                        base_prob = codon_prefix_dict[cutD_gen_seg[l_D_seg - delDr - 2:l_D_seg - delDr]][0]
                    else:
                        continue #no longer aligned, move to next delDr

                    #Enter main loop
                    for pos in range(init_pos - 3, max(init_pos - l_D_seg + delDr, min_pos)-1, -1):
                        #note delDl = D_pos
                        D_pos = l_D_seg - delDr - 1 - ((init_pos - 1) - pos)

                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if D_pos > self.max_delDl_given_DdelDr[D_in][delDr]:
                            current_PdelDldelDr = 0
                        else:
                            current_PdelDldelDr = self.PdelDldelDr_given_D[D_pos, delDr, D_in]
                        #Position is the first nt in codon
                        if pos%3 == 2:
                            #check alignment
                            if cutD_gen_seg[D_pos] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_nt_pos_vec[D_in][:, D_pos]
                            else:
                                break #no longer aligned -- exit loop
                        #Position is the second nt in codon
                        elif pos%3 == 1:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 2] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_2nd_nt_pos_per_aa_vec[D_in][CDR3_seq[pos/3]][ :, D_pos]
                            else:
                                break #no longer aligned --- exit loop
                        #Position is the last nt in codon
                        else:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 3] in self.codons_dict[CDR3_seq[pos/3]]:
                                Pi_R[0, pos] += current_PdelDldelDr*base_prob
                            else:
                                break #no longer aligned --- exit loop

            #start position is second nt in a codon
            for init_pos in range(-2,-len(CDR3_seq)*3-1,-3):
                Pi_R[:, init_pos] += Pi_JinsDJ_given_D[D_in][:, init_pos]*self.zeroD_given_D[D_in]
                allowed_final_nts = ['ACGT'[nt] for nt in range(4) if Pi_JinsDJ_given_D[D_in][nt, init_pos] > 0]

                for delDr in range(num_delr_pos):
                    if self.min_delDl_given_DdelDr[D_in][delDr] == -1: # P(delDr | D) = 0 for this delDr --> move to next
                        continue
                    #check first nt of the D region (last in the codon)
                    if cutD_gen_seg[l_D_seg - delDr - 1] in allowed_final_nts: #first nt match
                        base_prob = Pi_JinsDJ_given_D[D_in][nt2num[cutD_gen_seg[l_D_seg - delDr - 1]], init_pos]
                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if l_D_seg - delDr - 1 <= self.max_delDl_given_DdelDr[D_in][delDr]:
                            Pi_R[0, init_pos-1] += self.PdelDldelDr_given_D[l_D_seg - delDr - 1, delDr, D_in]*base_prob
                    else:
                        continue #no alignment

                    #Enter main loop
                    for pos in range(init_pos - 2, max(init_pos - l_D_seg + delDr, min_pos)-1, -1):
                        #note delDl = D_pos
                        D_pos = l_D_seg - delDr - 1 - ((init_pos - 1) - pos)

                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if D_pos > self.max_delDl_given_DdelDr[D_in][delDr]:
                            current_PdelDldelDr = 0
                        else:
                            current_PdelDldelDr = self.PdelDldelDr_given_D[D_pos, delDr, D_in]
                        #Position is the first nt in codon
                        if pos%3 == 2:
                            #check alignment
                            if cutD_gen_seg[D_pos] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_nt_pos_vec[D_in][:, D_pos]
                            else:
                                break #no longer aligned -- exit loop
                        #Position is the second nt in codon
                        elif pos%3 == 1:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 2] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_2nd_nt_pos_per_aa_vec[D_in][CDR3_seq[pos/3]][ :, D_pos]
                            else:
                                break #no longer aligned --- exit loop
                        #Position is the last nt in codon
                        else:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 3] in self.codons_dict[CDR3_seq[pos/3]]:
                                Pi_R[0, pos] += current_PdelDldelDr*base_prob
                            else:
                                break #no longer aligned --- exit loop

            #start position is last nt in a codon
            for init_pos in range(-3,-len(CDR3_seq)*3-1,-3):
                Pi_R[0, init_pos] += Pi_JinsDJ_given_D[D_in][0, init_pos]*self.zeroD_given_D[D_in]
                for delDr in range(num_delr_pos):
                    if self.min_delDl_given_DdelDr[D_in][delDr] == -1: # P(delDr | D) = 0 for this delDr --> move to next
                        continue
                    base_prob = Pi_JinsDJ_given_D[D_in][0, init_pos]
                    for pos in range(init_pos - 1, max(init_pos - l_D_seg + delDr, min_pos)-1, -1):
                        #note delDl = D_pos
                        D_pos = l_D_seg - delDr - 1 - ((init_pos - 1) - pos)

                        #The dell pos may be out of range of the PdelDldelDr_given_D -- check!
                        if D_pos > self.max_delDl_given_DdelDr[D_in][delDr]:
                            current_PdelDldelDr = 0
                        else:
                            current_PdelDldelDr = self.PdelDldelDr_given_D[D_pos, delDr, D_in]
                        #Position is the first nt in codon
                        if pos%3 == 2:
                            #check alignment
                            if cutD_gen_seg[D_pos] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_nt_pos_vec[D_in][:, D_pos]
                            else:
                                break #no longer aligned -- exit loop
                        #Position is the second nt in codon
                        elif pos%3 == 1:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 2] in self.sub_codons_right[CDR3_seq[pos/3]]:
                                Pi_R[:, pos] += current_PdelDldelDr*base_prob*self.PD_2nd_nt_pos_per_aa_vec[D_in][CDR3_seq[pos/3]][ :, D_pos]
                            else:
                                break #no longer aligned --- exit loop
                        #Position is the last nt in codon
                        else:
                            #check alignment
                            if cutD_gen_seg[D_pos:D_pos + 3] in self.codons_dict[CDR3_seq[pos/3]]:
                                Pi_R[0, pos] += current_PdelDldelDr*base_prob
                            else:
                                break #no longer aligned --- exit loop

        return Pi_R

Response: This function computes the Pi array from the model factors of the D and JV sequences and the model factors of the D and JV sequences.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def compute_CDR3_pgen(self, CDR3_seq, V_usage_mask, J_usage_mask):

        #Genomic J alignment/matching (contribution from P(delJ | J)), return Pi_J and reduced J_usage_mask
        Pi_J, r_J_usage_mask = self.compute_Pi_J(CDR3_seq, J_usage_mask)

        #Genomic V alignment/matching conditioned on J gene (contribution from P(V, J, delV)), return Pi_V_given_J
        Pi_V_given_J, max_V_align = self.compute_Pi_V_given_J(CDR3_seq, V_usage_mask, r_J_usage_mask)

        #Include insertions (R and PinsVJ) to get the total contribution from the left (3') side conditioned on J gene. Return Pi_V_insVJ_given_J
        Pi_V_insVJ_given_J = self.compute_Pi_V_insVJ_given_J(CDR3_seq, Pi_V_given_J, max_V_align)

        pgen = 0
        #zip Pi_V_insVJ_given_J and Pi_J together for each J gene to get total pgen
        for j in range(len(r_J_usage_mask)):
            for pos in range(len(CDR3_seq)*3 - 1):
                pgen += np.dot(Pi_V_insVJ_given_J[j][:, pos], Pi_J[j][:, pos+1])
        return pgen

Response: Compute the Pgen for a CDR3 amino acid sequence and return the Pi_J and reduced J_usage_mask.


Instruction:
Make a summary of the following Python 3 code
def compute_Pi_V_given_J(self, CDR3_seq, V_usage_mask, J_usage_mask):

        #Note, the cutV_genomic_CDR3_segs INCLUDE the palindromic insertions and thus are max_palindrome nts longer than the template.
        #furthermore, the genomic sequence should be pruned to start at the conserved C

        Pi_V_given_J = [np.zeros((4, len(CDR3_seq)*3)) for i in J_usage_mask] #Holds the aggregate weight for each nt possiblity and position
        alignment_lengths = []
        for V_in in V_usage_mask:
            try:
                cutV_gen_seg = self.cutV_genomic_CDR3_segs[V_in]
            except IndexError:
                print 'Check provided V usage mask. Contains indicies out of allowed range.'
                continue
            current_alignment_length = self.max_nt_to_aa_alignment_left(CDR3_seq, cutV_gen_seg)
            alignment_lengths += [current_alignment_length]
            current_Pi_V = np.zeros((4, len(CDR3_seq)*3))

            if current_alignment_length > 0:
                #For first and last nt in a codon use PVdelV_nt_pos_vec
                current_Pi_V[:, :current_alignment_length] = self.PVdelV_nt_pos_vec[V_in][:, :current_alignment_length]
                for pos in range(1, current_alignment_length, 3): #for middle nt use PVdelV_2nd_nt_pos_per_aa_vec
                    current_Pi_V[:, pos] = self.PVdelV_2nd_nt_pos_per_aa_vec[V_in][CDR3_seq[pos/3]][:, pos]
                for j, J_in in enumerate(J_usage_mask):
                    Pi_V_given_J[j][:, :current_alignment_length] += self.PVJ[V_in, J_in]*current_Pi_V[:, :current_alignment_length]

        return Pi_V_given_J, max(alignment_lengths)

Response: This function computes the Pi array for a given V and J.


Instruction:
Make a summary of the following Python 3 code
def compute_Pi_J(self, CDR3_seq, J_usage_mask):
        #Note, the cutJ_genomic_CDR3_segs INCLUDE the palindromic insertions and thus are max_palindrome nts longer than the template.
        #furthermore, the genomic sequence should be pruned to start at a conserved region on the J side

        Pi_J = [] #Holds the aggregate weight for each nt possiblity and position
        r_J_usage_mask = []
        for j, J_in in enumerate(J_usage_mask):
            try:
                cutJ_gen_seg = self.cutJ_genomic_CDR3_segs[J_in]
            except IndexError:
                print 'Check provided J usage mask. Contains indicies out of allowed range.'
                continue
            current_alignment_length = self.max_nt_to_aa_alignment_right(CDR3_seq, cutJ_gen_seg)
            #alignment_lengths += [current_alignment_length]
            current_Pi_J = np.zeros((4, len(CDR3_seq)*3))

            if current_alignment_length > 0:
                #For first and last nt in a codon use PJdelJ_nt_pos_vec
                current_Pi_J[:, -current_alignment_length:] = self.PJdelJ_nt_pos_vec[J_in][:, -current_alignment_length:]
                for pos in range(-2, -current_alignment_length-1, -3): #for middle nt use PJdelJ_2nd_nt_pos_per_aa_vec
                    current_Pi_J[:, pos] = self.PJdelJ_2nd_nt_pos_per_aa_vec[J_in][CDR3_seq[pos/3]][:, pos]
                if np.sum(current_Pi_J) > 0:
                    Pi_J.append(current_Pi_J)
                    r_J_usage_mask.append(J_in)

        return Pi_J, r_J_usage_mask

Response: This function computes the Pi array corresponding to the J genomic nucleotide sequence and the J_usage mask.


Instruction:
Can you tell what is the following Python 3 function doing
def solve(self, lam):
        '''Solves the GFL for a fixed value of lambda.'''
        s = weighted_graphtf(self.nnodes, self.y, self.weights, lam,
                             self.Dk.shape[0], self.Dk.shape[1], self.Dk.nnz,
                             self.Dk.row.astype('int32'), self.Dk.col.astype('int32'), self.Dk.data.astype('double'),
                             self.maxsteps, self.converge,
                             self.beta, self.u)
        self.steps.append(s)
        return self.beta

Response: Solves the GFL for a fixed value of lambda.


Instruction:
How would you implement a function in Python 3 that
follows the solution path to find the best lambda value.

Response:
def solution_path(self, min_lambda, max_lambda, lambda_bins, verbose=0):
        '''Follows the solution path to find the best lambda value.'''
        self.u = np.zeros(self.Dk.shape[0], dtype='double')
        lambda_grid = np.exp(np.linspace(np.log(max_lambda), np.log(min_lambda), lambda_bins))
        aic_trace = np.zeros(lambda_grid.shape) # The AIC score for each lambda value
        aicc_trace = np.zeros(lambda_grid.shape) # The AICc score for each lambda value (correcting for finite sample size)
        bic_trace = np.zeros(lambda_grid.shape) # The BIC score for each lambda value
        dof_trace = np.zeros(lambda_grid.shape) # The degrees of freedom of each final solution
        log_likelihood_trace = np.zeros(lambda_grid.shape)
        beta_trace = []
        best_idx = None
        best_plateaus = None

        if self.edges is None:
            self.edges = defaultdict(list)
            elist = csr_matrix(self.D).indices.reshape((self.D.shape[0], 2))
            for n1, n2 in elist:
                self.edges[n1].append(n2)
                self.edges[n2].append(n1)

        # Solve the series of lambda values with warm starts at each point
        for i, lam in enumerate(lambda_grid):
            if verbose:
                print('#{0} Lambda = {1}'.format(i, lam))

            # Fit to the final values
            beta = self.solve(lam)

            if verbose:
                print('Calculating degrees of freedom')

            # Count the number of free parameters in the grid (dof) -- TODO: the graph trend filtering paper seems to imply we shouldn't multiply by (k+1)?
            dof_vals = self.Dk_minus_one.dot(beta) if self.k > 0 else beta
            plateaus = calc_plateaus(dof_vals, self.edges, rel_tol=0.01) if (self.k % 2) == 0 else nearly_unique(dof_vals, rel_tol=0.03)
            dof_trace[i] = max(1,len(plateaus)) #* (k+1)

            if verbose:
                print('Calculating Information Criteria')

            # Get the negative log-likelihood
            log_likelihood_trace[i] = -0.5 * ((self.y - beta)**2).sum()

            # Calculate AIC = 2k - 2ln(L)
            aic_trace[i] = 2. * dof_trace[i] - 2. * log_likelihood_trace[i]

            # Calculate AICc = AIC + 2k * (k+1) / (n - k - 1)
            aicc_trace[i] = aic_trace[i] + 2 * dof_trace[i] * (dof_trace[i]+1) / (len(beta) - dof_trace[i] - 1.)

            # Calculate BIC = -2ln(L) + k * (ln(n) - ln(2pi))
            bic_trace[i] = -2 * log_likelihood_trace[i] + dof_trace[i] * (np.log(len(beta)) - np.log(2 * np.pi))

            # Track the best model thus far
            if best_idx is None or bic_trace[i] < bic_trace[best_idx]:
                best_idx = i
                best_plateaus = plateaus

            # Save the trace of all the resulting parameters
            beta_trace.append(np.array(beta))

            if verbose:
                print('DoF: {0} AIC: {1} AICc: {2} BIC: {3}\n'.format(dof_trace[i], aic_trace[i], aicc_trace[i], bic_trace[i]))

        if verbose:
            print('Best setting (by BIC): lambda={0} [DoF: {1}, AIC: {2}, AICc: {3} BIC: {4}]'.format(lambda_grid[best_idx], dof_trace[best_idx], aic_trace[best_idx], aicc_trace[best_idx], bic_trace[best_idx]))

        return {'aic': aic_trace,
                'aicc': aicc_trace,
                'bic': bic_trace,
                'dof': dof_trace,
                'loglikelihood': log_likelihood_trace,
                'beta': np.array(beta_trace),
                'lambda': lambda_grid,
                'best_idx': best_idx,
                'best': beta_trace[best_idx],
                'plateaus': best_plateaus}


Instruction:
Write a Python 3 script for
solving the GFL for a fixed value of lambda.

Response:
def solve(self, lam):
        '''Solves the GFL for a fixed value of lambda.'''
        s = weighted_graphtf_logit(self.nnodes, self.trials, self.successes, lam,
                                 self.Dk.shape[0], self.Dk.shape[1], self.Dk.nnz,
                                 self.Dk.row.astype('int32'), self.Dk.col.astype('int32'), self.Dk.data.astype('double'),
                                 self.maxsteps, self.converge,
                                 self.beta, self.u)
        self.steps.append(s)
        return self.beta


Instruction:
Write a Python 3 function that can
solve the GFL for a fixed value of lambda.

Response:
def solve(self, lam):
        '''Solves the GFL for a fixed value of lambda.'''
        s = weighted_graphtf_poisson(self.nnodes, self.obs, lam,
                                 self.Dk.shape[0], self.Dk.shape[1], self.Dk.nnz,
                                 self.Dk.row.astype('int32'), self.Dk.col.astype('int32'), self.Dk.data.astype('double'),
                                 self.maxsteps, self.converge,
                                 self.beta, self.u)
        self.steps.append(s)
        return self.beta


Instruction:
Write a Python 3 script to
construct the V and J mask mapping dictionaries.

Response:
def make_V_and_J_mask_mapping(self, genV, genJ):
        """Constructs the V and J mask mapping dictionaries.

        Parameters
        ----------
        genV : list
            List of genomic V information.
        genJ : list
            List of genomic J information.

        """
        #construct mapping between allele/gene names and index for custom V_usage_masks
        V_allele_names = [V[0] for V in genV]
        V_mask_mapping = {}
        for v in set([x.split('*')[0] for x in V_allele_names]):
            V_mask_mapping[v] = []
        for v in set(['V'.join((x.split('*')[0]).split('V')[1:]) for x in V_allele_names]):
            V_mask_mapping[v] = []
        for i, v in enumerate(V_allele_names):
            V_mask_mapping[v] = [i]
            V_mask_mapping['V'.join((v.split('*')[0]).split('V')[1:])].append(i)
            V_mask_mapping[v.split('*')[0]].append(i)

        #construct mapping between allele/gene names and index for custom J_usage_masks
        J_allele_names = [J[0] for J in genJ]
        J_mask_mapping = {}
        for j in set([x.split('*')[0] for x in J_allele_names]):
            J_mask_mapping[j] = []
        for j in set(['J'.join((x.split('*')[0]).split('J')[1:]) for x in J_allele_names]):
            J_mask_mapping[j] = []
        for i, j in enumerate(J_allele_names):
            J_mask_mapping[j] = [i]
            J_mask_mapping['J'.join((j.split('*')[0]).split('J')[1:])].append(i)
            J_mask_mapping[j.split('*')[0]].append(i)

        self.V_allele_names = V_allele_names
        self.V_mask_mapping = V_mask_mapping
        self.J_allele_names = J_allele_names
        self.J_mask_mapping = J_mask_mapping


Instruction:
Can you generate the documentation for the following Python 3 function
def preprocess_D_segs(self, generative_model, genomic_data):

        cutD_genomic_CDR3_segs = genomic_data.cutD_genomic_CDR3_segs
        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
        num_dell_pos, num_delr_pos, num_D_genes = generative_model.PdelDldelDr_given_D.shape

        #These arrays only include the nt identity information, not the PdelDldelDr_given_D info
        PD_nt_pos_vec = [[]]*num_D_genes
        PD_2nd_nt_pos_per_aa_vec = [[]]*num_D_genes
        for D_in in range(num_D_genes):

            current_PD_nt_pos_vec = np.zeros((4, len(cutD_genomic_CDR3_segs[D_in])))
            current_PD_2nd_nt_pos_per_aa_vec = {}
            for aa in self.codons_dict.keys():
                current_PD_2nd_nt_pos_per_aa_vec[aa] = np.zeros((4, len(cutD_genomic_CDR3_segs[D_in])))

            for pos, nt in enumerate(cutD_genomic_CDR3_segs[D_in]):
                current_PD_nt_pos_vec[nt2num[nt], pos] = 1
                for ins_nt in 'ACGT':
                    for aa in self.codons_dict.keys():
                        if ins_nt + cutD_genomic_CDR3_segs[D_in][pos:pos+2] in self.codons_dict[aa]:
                            current_PD_2nd_nt_pos_per_aa_vec[aa][nt2num[ins_nt], pos] = 1

            PD_nt_pos_vec[D_in] = current_PD_nt_pos_vec
            PD_2nd_nt_pos_per_aa_vec[D_in] = current_PD_2nd_nt_pos_per_aa_vec

        min_delDl_given_DdelDr = [[]]*num_D_genes
        max_delDl_given_DdelDr = [[]]*num_D_genes
        zeroD_given_D = [[]]*num_D_genes
        for D_in in range(num_D_genes):
            current_min_delDl_given_delDr = [0]*num_delr_pos
            current_max_delDl_given_delDr = [0]*num_delr_pos
            current_zeroD = 0
            for delr in range(num_delr_pos):

                if num_dell_pos > len(cutD_genomic_CDR3_segs[D_in])-delr:
                    current_zeroD += generative_model.PdelDldelDr_given_D[len(cutD_genomic_CDR3_segs[D_in])-delr, delr, D_in]

                dell = 0
                while generative_model.PdelDldelDr_given_D[dell, delr, D_in]==0 and dell<num_dell_pos-1:
                    dell+=1
                if generative_model.PdelDldelDr_given_D[dell, delr, D_in] == 0:
                    current_min_delDl_given_delDr[delr] = -1
                else:
                    current_min_delDl_given_delDr[delr] = dell
                if current_min_delDl_given_delDr[delr] == -1:
                    current_max_delDl_given_delDr[delr] = -1
                else:
                    dell = num_dell_pos-1
                    while generative_model.PdelDldelDr_given_D[dell, delr, D_in]==0 and dell>=0:
                        dell -= 1
                    if generative_model.PdelDldelDr_given_D[dell, delr, D_in] == 0:
                        current_max_delDl_given_delDr[delr] = -1
                    else:
                        current_max_delDl_given_delDr[delr] = dell

            min_delDl_given_DdelDr[D_in] = current_min_delDl_given_delDr
            max_delDl_given_DdelDr[D_in] = current_max_delDl_given_delDr
            zeroD_given_D[D_in] = current_zeroD

        self.PD_nt_pos_vec = PD_nt_pos_vec
        self.PD_2nd_nt_pos_per_aa_vec = PD_2nd_nt_pos_per_aa_vec
        self.min_delDl_given_DdelDr = min_delDl_given_DdelDr
        self.max_delDl_given_DdelDr = max_delDl_given_DdelDr
        self.zeroD_given_D = zeroD_given_D

Response: Preprocess the D sequences into Pi arrays.


Instruction:
Create a Python 3 function for
generating the PJdelJ_nt_pos_vec and PJdelJ_2nd_nt_pos_per_aa_vec attributes for the VDJ object.

Response:
def generate_PJdelJ_nt_pos_vecs(self, generative_model, genomic_data):
        """Process P(J)*P(delJ|J) into Pi arrays.

        Sets the attributes PJdelJ_nt_pos_vec and PJdelJ_2nd_nt_pos_per_aa_vec.

        Parameters
        ----------
        generative_model : GenerativeModelVDJ
            VDJ generative model class containing the model parameters.
        genomic_data : GenomicDataVDJ
            VDJ genomic data class containing the V, D, and J germline
            sequences and info.

        """

        cutJ_genomic_CDR3_segs = genomic_data.cutJ_genomic_CDR3_segs
        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
        num_del_pos = generative_model.PdelJ_given_J.shape[0]

        num_D_genes, num_J_genes = generative_model.PDJ.shape
        PJ = np.sum(generative_model.PDJ, axis = 0)

        PJdelJ_nt_pos_vec = [[]]*num_J_genes
        PJdelJ_2nd_nt_pos_per_aa_vec = [[]]*num_J_genes
        for J_in, pj in enumerate(PJ):
            #We include the marginal PJ here
            current_PJdelJ_nt_pos_vec = np.zeros((4, len(cutJ_genomic_CDR3_segs[J_in])))
            current_PJdelJ_2nd_nt_pos_per_aa_vec  = {}
            for aa in self.codons_dict.keys():
                current_PJdelJ_2nd_nt_pos_per_aa_vec[aa] = np.zeros((4, len(cutJ_genomic_CDR3_segs[J_in])))

            for pos, nt in enumerate(cutJ_genomic_CDR3_segs[J_in]):
                if pos >=  num_del_pos:
                    continue
                if (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 1: #Start of a codon
                    current_PJdelJ_nt_pos_vec[nt2num[nt], pos] = pj*generative_model.PdelJ_given_J[pos, J_in]
                elif (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 2: #Mid codon position
                    for ins_nt in 'ACGT':
                        #We need to find what possible codons are allowed for any aa (or motif)
                        for aa in self.codons_dict.keys():
                            if ins_nt + cutJ_genomic_CDR3_segs[J_in][pos:pos+2] in self.codons_dict[aa]:
                                current_PJdelJ_2nd_nt_pos_per_aa_vec[aa][nt2num[ins_nt], pos] = pj*generative_model.PdelJ_given_J[pos, J_in]

                elif (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 0: #End  of codon
                    current_PJdelJ_nt_pos_vec[0, pos] = pj*generative_model.PdelJ_given_J[pos, J_in]
            PJdelJ_nt_pos_vec[J_in] = current_PJdelJ_nt_pos_vec
            PJdelJ_2nd_nt_pos_per_aa_vec[J_in] = current_PJdelJ_2nd_nt_pos_per_aa_vec

        self.PJdelJ_nt_pos_vec = PJdelJ_nt_pos_vec
        self.PJdelJ_2nd_nt_pos_per_aa_vec = PJdelJ_2nd_nt_pos_per_aa_vec


Instruction:
Given the following Python 3 function, write the documentation
def generate_VD_junction_transfer_matrices(self):

        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}

        #Compute Tvd
        Tvd = {}
        for aa in self.codons_dict.keys():
            current_Tvd = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Tvd[nt2num[codon[2]], nt2num[init_nt]] += self.Rvd[nt2num[codon[2]],nt2num[codon[1]]]*self.Rvd[nt2num[codon[1]],nt2num[codon[0]]] * self.Rvd[nt2num[codon[0]],nt2num[init_nt]]
            Tvd[aa] = current_Tvd

        #Compute Svd
        Svd = {}
        for aa in self.codons_dict.keys():
            current_Svd = np.zeros((4, 4))
            for ins_nt in 'ACGT':
                if any([codon.startswith(ins_nt) for codon in self.codons_dict[aa]]):
                    current_Svd[nt2num[ins_nt], :] = self.Rvd[nt2num[ins_nt], :]

            Svd[aa] = current_Svd

        #Compute Dvd
        Dvd = {}
        for aa in self.codons_dict.keys():
            current_Dvd = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Dvd[nt2num[codon[2]], nt2num[init_nt]] += self.Rvd[nt2num[codon[1]],nt2num[codon[0]]] * self.Rvd[nt2num[codon[0]],nt2num[init_nt]]
            Dvd[aa] = current_Dvd

        #Compute lTvd
        lTvd = {}
        for aa in self.codons_dict.keys():
            current_lTvd = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_lTvd[nt2num[codon[2]], nt2num[codon[0]]] += self.Rvd[nt2num[codon[2]],nt2num[codon[1]]]*self.first_nt_bias_insVD[nt2num[codon[1]]]
            lTvd[aa] = current_lTvd

        #Compute lDvd
        lDvd = {}
        for aa in self.codons_dict.keys():
            current_lDvd = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_lDvd[nt2num[codon[2]], nt2num[codon[0]]] += self.first_nt_bias_insVD[nt2num[codon[1]]]
            lDvd[aa] = current_lDvd

        #Set the attributes
        self.Tvd = Tvd
        self.Svd = Svd
        self.Dvd = Dvd
        self.lTvd = lTvd
        self.lDvd = lDvd

Response: Compute the transfer matrices for the VD junction.


Instruction:
Given the following Python 3 function, write the documentation
def generate_DJ_junction_transfer_matrices(self):

        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}

        #Compute Tdj
        Tdj = {}
        for aa in self.codons_dict.keys():
            current_Tdj = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Tdj[nt2num[codon[0]], nt2num[init_nt]] += self.Rdj[nt2num[codon[0]],nt2num[codon[1]]]*self.Rdj[nt2num[codon[1]],nt2num[codon[2]]] * self.Rdj[nt2num[codon[2]],nt2num[init_nt]]
            Tdj[aa] = current_Tdj

        #Compute Sdj
        Sdj = {}
        for aa in self.codons_dict.keys():
            current_Sdj = np.zeros((4, 4))
            for ins_nt in 'ACGT':
                if any([codon.endswith(ins_nt) for codon in self.codons_dict[aa]]):
                    current_Sdj[nt2num[ins_nt], :] = self.Rdj[nt2num[ins_nt], :]
            Sdj[aa] = current_Sdj

        #Compute Ddj
        Ddj = {}
        for aa in self.codons_dict.keys():
            current_Ddj = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Ddj[nt2num[codon[0]], nt2num[init_nt]] += self.Rdj[nt2num[codon[1]],nt2num[codon[2]]] * self.Rdj[nt2num[codon[2]],nt2num[init_nt]]
            Ddj[aa] = current_Ddj

        #Compute rTdj
        rTdj = {}
        for aa in self.codons_dict.keys():
            current_lTdj = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_lTdj[nt2num[codon[0]], nt2num[codon[2]]] += self.Rdj[nt2num[codon[0]],nt2num[codon[1]]]*self.first_nt_bias_insDJ[nt2num[codon[1]]]
            rTdj[aa] = current_lTdj

        #Compute rDdj
        rDdj = {}
        for aa in self.codons_dict.keys():
            current_rDdj = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_rDdj[nt2num[codon[0]], nt2num[codon[2]]] += self.first_nt_bias_insDJ[nt2num[codon[1]]]
            rDdj[aa] = current_rDdj

        #Set the attributes
        self.Tdj = Tdj
        self.Sdj = Sdj
        self.Ddj = Ddj
        self.rTdj = rTdj
        self.rDdj = rDdj

Response: Compute the transfer matrices for the VD junction.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def generate_PVdelV_nt_pos_vecs(self, generative_model, genomic_data):

        cutV_genomic_CDR3_segs = genomic_data.cutV_genomic_CDR3_segs
        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
        num_del_pos = generative_model.PdelV_given_V.shape[0]
        num_V_genes = generative_model.PdelV_given_V.shape[1]
        PVdelV_nt_pos_vec = [[]]*num_V_genes
        PVdelV_2nd_nt_pos_per_aa_vec = [[]]*num_V_genes
        for V_in in range(num_V_genes):
            current_PVdelV_nt_pos_vec = np.zeros((4, len(cutV_genomic_CDR3_segs[V_in])))
            current_PVdelV_2nd_nt_pos_per_aa_vec = {}
            for aa in self.codons_dict.keys():
                current_PVdelV_2nd_nt_pos_per_aa_vec[aa] = np.zeros((4, len(cutV_genomic_CDR3_segs[V_in])))
            for pos, nt in enumerate(cutV_genomic_CDR3_segs[V_in]):
                if len(cutV_genomic_CDR3_segs[V_in]) - pos >  num_del_pos:
                    continue
                if pos%3 == 0: #Start of a codon
                    current_PVdelV_nt_pos_vec[nt2num[nt], pos] = generative_model.PdelV_given_V[len(cutV_genomic_CDR3_segs[V_in])-pos-1, V_in]
                elif pos%3 == 1: #Mid codon position
                    for ins_nt in 'ACGT':
                        #We need to find what possible codons are allowed for any aa (or motif)
                        for aa in self.codons_dict.keys():
                            if cutV_genomic_CDR3_segs[V_in][pos-1:pos+1]+ ins_nt in self.codons_dict[aa]:
                                current_PVdelV_2nd_nt_pos_per_aa_vec[aa][nt2num[ins_nt], pos] = generative_model.PdelV_given_V[len(cutV_genomic_CDR3_segs[V_in])-pos-1, V_in]
                elif pos%3 == 2: #End of codon
                    current_PVdelV_nt_pos_vec[0, pos] = generative_model.PdelV_given_V[len(cutV_genomic_CDR3_segs[V_in])-pos-1, V_in]
            PVdelV_nt_pos_vec[V_in] = current_PVdelV_nt_pos_vec
            PVdelV_2nd_nt_pos_per_aa_vec[V_in] = current_PVdelV_2nd_nt_pos_per_aa_vec

        self.PVdelV_nt_pos_vec = PVdelV_nt_pos_vec
        self.PVdelV_2nd_nt_pos_per_aa_vec = PVdelV_2nd_nt_pos_per_aa_vec

Response: Generate the PVdelV_nt_pos_vec and PVdelV_2nd_nt_pos_per_aa_vec attributes for the V and J germlinevines.


Instruction:
Write a Python 3 script to
generate the PJdelJ NT positives vectors for the given V and J.

Response:
def generate_PJdelJ_nt_pos_vecs(self, generative_model, genomic_data):
        """Process P(delJ|J) into Pi arrays.

        Set the attributes PJdelJ_nt_pos_vec and PJdelJ_2nd_nt_pos_per_aa_vec.

        Parameters
        ----------
        generative_model : GenerativeModelVJ
            VJ generative model class containing the model parameters.
        genomic_data : GenomicDataVJ
            VJ genomic data class containing the V and J germline
            sequences and info.

        """

        cutJ_genomic_CDR3_segs = genomic_data.cutJ_genomic_CDR3_segs
        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}
        num_del_pos = generative_model.PdelJ_given_J.shape[0]

        num_D_genes, num_J_genes = generative_model.PVJ.shape

        PJdelJ_nt_pos_vec = [[]]*num_J_genes
        PJdelJ_2nd_nt_pos_per_aa_vec = [[]]*num_J_genes
        for J_in in range(num_J_genes):
            current_PJdelJ_nt_pos_vec = np.zeros((4, len(cutJ_genomic_CDR3_segs[J_in])))
            current_PJdelJ_2nd_nt_pos_per_aa_vec  = {}
            for aa in self.codons_dict.keys():
                current_PJdelJ_2nd_nt_pos_per_aa_vec[aa] = np.zeros((4, len(cutJ_genomic_CDR3_segs[J_in])))

            for pos, nt in enumerate(cutJ_genomic_CDR3_segs[J_in]):
                if pos >=  num_del_pos:
                    continue
                if (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 1: #Start of a codon
                    current_PJdelJ_nt_pos_vec[nt2num[nt], pos] = generative_model.PdelJ_given_J[pos, J_in]
                elif (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 2: #Mid codon position
                    for ins_nt in 'ACGT':
                        #We need to find what possible codons are allowed for any aa (or motif)
                        for aa in self.codons_dict.keys():
                            if ins_nt + cutJ_genomic_CDR3_segs[J_in][pos:pos+2] in self.codons_dict[aa]:
                                current_PJdelJ_2nd_nt_pos_per_aa_vec[aa][nt2num[ins_nt], pos] = generative_model.PdelJ_given_J[pos, J_in]

                elif (len(cutJ_genomic_CDR3_segs[J_in]) - pos)%3 == 0: #End  of codon
                    current_PJdelJ_nt_pos_vec[0, pos] = generative_model.PdelJ_given_J[pos, J_in]
            PJdelJ_nt_pos_vec[J_in] = current_PJdelJ_nt_pos_vec
            PJdelJ_2nd_nt_pos_per_aa_vec[J_in] = current_PJdelJ_2nd_nt_pos_per_aa_vec

        self.PJdelJ_nt_pos_vec = PJdelJ_nt_pos_vec
        self.PJdelJ_2nd_nt_pos_per_aa_vec = PJdelJ_2nd_nt_pos_per_aa_vec


Instruction:
Can you tell what is the following Python 3 function doing
def generate_VJ_junction_transfer_matrices(self):

        nt2num = {'A': 0, 'C': 1, 'G': 2, 'T': 3}

        #Compute Tvj
        Tvj = {}
        for aa in self.codons_dict.keys():
            current_Tvj = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Tvj[nt2num[codon[2]], nt2num[init_nt]] += self.Rvj[nt2num[codon[2]],nt2num[codon[1]]]*self.Rvj[nt2num[codon[1]],nt2num[codon[0]]] * self.Rvj[nt2num[codon[0]],nt2num[init_nt]]
            Tvj[aa] = current_Tvj

        #Compute Svj
        Svj = {}
        for aa in self.codons_dict.keys():
            current_Svj = np.zeros((4, 4))
            for ins_nt in 'ACGT':
                if any([codon.startswith(ins_nt) for codon in self.codons_dict[aa]]):
                    current_Svj[nt2num[ins_nt], :] = self.Rvj[nt2num[ins_nt], :]
            Svj[aa] = current_Svj

        #Compute Dvj
        Dvj = {}
        for aa in self.codons_dict.keys():
            current_Dvj = np.zeros((4, 4))
            for init_nt in 'ACGT':
                for codon in self.codons_dict[aa]:
                    current_Dvj[nt2num[codon[2]], nt2num[init_nt]] += self.Rvj[nt2num[codon[1]],nt2num[codon[0]]] * self.Rvj[nt2num[codon[0]],nt2num[init_nt]]
            Dvj[aa] = current_Dvj

        #Compute lTvj
        lTvj = {}
        for aa in self.codons_dict.keys():
            current_lTvj = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_lTvj[nt2num[codon[2]], nt2num[codon[0]]] += self.Rvj[nt2num[codon[2]],nt2num[codon[1]]]*self.first_nt_bias_insVJ[nt2num[codon[1]]]
            lTvj[aa] = current_lTvj

        #Compute lDvj
        lDvj = {}
        for aa in self.codons_dict.keys():
            current_lDvj = np.zeros((4, 4))
            for codon in self.codons_dict[aa]:
                current_lDvj[nt2num[codon[2]], nt2num[codon[0]]] += self.first_nt_bias_insVJ[nt2num[codon[1]]]
            lDvj[aa] = current_lDvj

        #Set the attributes
        self.Tvj = Tvj
        self.Svj = Svj
        self.Dvj = Dvj
        self.lTvj = lTvj
        self.lDvj = lDvj

Response: Generate the transfer matrices for the VJ junction.


Instruction:
How would you implement a function in Python 3 that
prints the DATA_DIRECTORY fields.

Response:
def showDataDirectoriesData(peInstance):
    """ Prints the DATA_DIRECTORY fields. """

    print "[+] Data directories:\n"
    dirs = peInstance.ntHeaders.optionalHeader.dataDirectory
    counter = 1
    for dir in dirs:
        print "[%d] --> Name: %s -- RVA: 0x%08x -- SIZE: 0x%08x" % (counter,  dir.name.value,  dir.rva.value,  dir.size.value)
        counter += 1


Instruction:
Can you tell what is the following Python 3 function doing
def showSectionsHeaders(peInstance):

    print "[+] Sections information:\n"
    print "--> NumberOfSections: %d\n" % peInstance.ntHeaders.fileHeader.numberOfSections.value
    for section in peInstance.sectionHeaders:
        fields = section.getFields()
        for field in fields:
            if isinstance(fields[field],  datatypes.String):
                fmt = "%s = %s"
            else:
                fmt = "%s = 0x%08x"
            print fmt % (field,  fields[field].value)
        print "\n"

Response: Prints IMAGE_SECTION_HEADER for every section present in the file.


Instruction:
Make a summary of the following Python 3 code
def showImports(peInstance):

    iidEntries = peInstance.ntHeaders.optionalHeader.dataDirectory[consts.IMPORT_DIRECTORY].info
    if iidEntries:
        for iidEntry in iidEntries:
            fields = iidEntry.getFields()
            print "module: %s" % iidEntry.metaData.moduleName.value
            for field in fields:
                print "%s -> %x" % (field,  fields[field].value)

            for iatEntry in iidEntry.iat:
                fields = iatEntry.getFields()
                for field in fields:
                    print "%s - %r" % (field,  fields[field].value)

            print "\n"
    else:
        print "The file does not have imported functions."

Response: Shows the imports information.


Instruction:
Here you have a function in Python 3, explain what it does
def getFields(self):
        d = {}
        for i in self._attrsList:
            key = i
            value = getattr(self,  i)
            d[key] = value
        return d

Response: Returns all the class attributues.


Instruction:
How would you implement a function in Python 3 that
parses the contents of the n - bit array and returns a new array.

Response:
def parse(readDataInstance,  arrayType,  arrayLength):
        """
        Returns a new L{Array} object.

        @type readDataInstance: L{ReadData}
        @param readDataInstance: The L{ReadData} object containing the array data.

        @type arrayType: int
        @param arrayType: The type of L{Array} to be built.

        @type arrayLength: int
        @param arrayLength: The length of the array passed as an argument.

        @rtype: L{Array}
        @return: New L{Array} object.
        """
        newArray = Array(arrayType)

        dataLength = len(readDataInstance)

        if arrayType is TYPE_DWORD:
            toRead = arrayLength * 4
            if dataLength >= toRead:
                for i in range(arrayLength):
                    newArray.append(DWORD(readDataInstance.readDword()))
            else:
                raise excep.DataLengthException("Not enough bytes to read.")

        elif arrayType is TYPE_WORD:
            toRead = arrayLength * 2
            if dataLength >= toRead:
                for i in range(arrayLength):
                    newArray.append(DWORD(readDataInstance.readWord()))
            else:
                raise excep.DataLengthException("Not enough bytes to read.")

        elif arrayType is TYPE_QWORD:
            toRead = arrayLength * 8
            if dataLength >= toRead:
                for i in range(arrayLength):
                    newArray.append(QWORD(readDataInstance.readQword()))
            else:
                raise excep.DataLengthException("Not enough bytes to read.")

        elif arrayType is TYPE_BYTE:
            for i in range(arrayLength):
                newArray.append(BYTE(readDataInstance.readByte()))

        else:
            raise excep.ArrayTypeException("Could\'t create an array of type %d" % arrayType)

        return newArray


Instruction:
How would you explain what the following Python 3 function does
def calc_euler_tour(g, start, end):
    '''Calculates an Euler tour over the graph g from vertex start to vertex end.
    Assumes start and end are odd-degree vertices and that there are no other odd-degree
    vertices.'''
    even_g = nx.subgraph(g, g.nodes()).copy()
    if end in even_g.neighbors(start):
        # If start and end are neighbors, remove the edge
        even_g.remove_edge(start, end)
        comps = list(nx.connected_components(even_g))
        # If the graph did not split, just find the euler circuit
        if len(comps) == 1:
            trail = list(nx.eulerian_circuit(even_g, start))
            trail.append((start, end))
        elif len(comps) == 2:
            subg1 = nx.subgraph(even_g, comps[0])
            subg2 = nx.subgraph(even_g, comps[1])
            start_subg, end_subg = (subg1, subg2) if start in subg1.nodes() else (subg2, subg1)
            trail = list(nx.eulerian_circuit(start_subg, start)) + [(start, end)] + list(nx.eulerian_circuit(end_subg, end))
        else:
            raise Exception('Unknown edge case with connected components of size {0}:\n{1}'.format(len(comps), comps))
    else:
        # If they are not neighbors, we add an imaginary edge and calculate the euler circuit
        even_g.add_edge(start, end)
        circ = list(nx.eulerian_circuit(even_g, start))
        try:
            trail_start = circ.index((start, end))
        except:
            trail_start = circ.index((end, start))
        trail = circ[trail_start+1:] + circ[:trail_start]
    return trail

Response: Calculates an Euler tour over the graph g from vertex start to vertex end.


Instruction:
How would you explain what the following Python 3 function does
def greedy_trails(subg, odds, verbose):
    '''Greedily select trails by making the longest you can until the end'''
    if verbose:
        print('\tCreating edge map')

    edges = defaultdict(list)

    for x,y in subg.edges():
        edges[x].append(y)
        edges[y].append(x)

    if verbose:
        print('\tSelecting trails')

    trails = []
    for x in subg.nodes():
        if verbose > 2:
            print('\t\tNode {0}'.format(x))

        while len(edges[x]) > 0:
            y = edges[x][0]
            trail = [(x,y)]
            edges[x].remove(y)
            edges[y].remove(x)
            while len(edges[y]) > 0:
                x = y
                y = edges[y][0]
                trail.append((x,y))
                edges[x].remove(y)
                edges[y].remove(x)
            trails.append(trail)
    return trails

Response: Greedily select trails by making the longest you can until the end.


Instruction:
Implement a function in Python 3 to
decompose a graph into a set of non - overlapping trails.

Response:
def decompose_graph(g, heuristic='tour', max_odds=20, verbose=0):
    '''Decompose a graph into a set of non-overlapping trails.'''
    # Get the connected subgraphs
    subgraphs = [nx.subgraph(g, x).copy() for x in nx.connected_components(g)]

    chains = []
    num_subgraphs = len(subgraphs)
    step = 0
    while num_subgraphs > 0:
        if verbose:
            print('Step #{0} ({1} subgraphs)'.format(step, num_subgraphs))

        for i in range(num_subgraphs-1, -1, -1):
            subg = subgraphs[i]

            # Get all odd-degree nodes
            odds = [x for x,y in dict(nx.degree(subg)).items() if y % 2 == 1]

            if verbose > 1:
                if len(odds) == 0:
                    print('\t\tNo odds')
                elif len(odds) == 2:
                    print('\t\tExactly 2 odds')
                else:
                    print('\t\t{0} odds'.format(len(odds)))

            # If there are no odd-degree edges, we can find an euler circuit
            if len(odds) == 0:
                trails = [list(nx.eulerian_circuit(subg))]
            elif len(odds) == 2:
                # If there are only two odd-degree edges, we can find an euler tour
                trails = [calc_euler_tour(subg, odds[0], odds[1])]
            elif heuristic in ['min', 'max', 'median', 'any']:
                trails = select_odd_degree_trail(subg, odds, max_odds, heuristic, verbose)
            elif heuristic == 'random':
                trails = select_random_trail(subg, verbose)
            elif heuristic == 'mindegree':
                trails = select_min_degree_trail(subg, max_odds, verbose)
            elif heuristic == 'ones':
                trails = select_single_edge_trails(subg, verbose)
            elif heuristic == 'tour':
                trails = pseudo_tour_trails(subg, odds, verbose)
            elif heuristic == 'greedy':
                trails = greedy_trails(subg, odds, verbose)

            if verbose > 2:
                print('\t\tTrails: {0}'.format(len(trails)))

            # Remove the trail
            for trail in trails:
                subg.remove_edges_from(trail)

            # Add it to the list of chains
            chains.extend(trails)

            # If the subgraph is empty, remove it from the list
            if subg.number_of_edges() == 0:
                del subgraphs[i]
            else:
                comps = list(nx.connected_components(subg))

                # If the last edge split the graph, add the new subgraphs to the list of subgraphs
                if len(comps) > 1:
                    for x in comps:
                        compg = nx.subgraph(subg, x)
                        if compg.number_of_edges() > 0:
                            subgraphs.append(compg)
                    del subgraphs[i]

        # Update the count of connected subgraphs
        num_subgraphs = len(subgraphs)
        step += 1

    return chains


Instruction:
Write a Python 3 script to
return a new Vector with the x y and z added.

Response:
def plus(self, a):
        """ Add. """
        return Vector(self.x+a.x, self.y+a.y, self.z+a.z)


Instruction:
Can you tell what is the following Python 3 function doing
def minus(self, a):
        return Vector(self.x-a.x, self.y-a.y, self.z-a.z)

Response: Subtracts the vector a from self.


Instruction:
Can you generate the documentation for the following Python 3 function
def times(self, a):
        return Vector(self.x*a, self.y*a, self.z*a)

Response: Multiply the Vector by a number.


Instruction:
Write a Python 3 function for
dividing by a vector.

Response:
def dividedBy(self, a):
        """ Divide. """
        return Vector(self.x/a, self.y/a, self.z/a)


Instruction:
Create a Python 3 function to
create a new vertex between this vertex and other by linearly interpolating all properties using a parameter of t.

Response:
def interpolate(self, other, t):
        """
        Create a new vertex between this vertex and `other` by linearly
        interpolating all properties using a parameter of `t`. Subclasses should
        override this to interpolate additional properties.
        """
        return Vertex(self.pos.lerp(other.pos, t),
                          self.normal.lerp(other.normal, t))