def compute_Pi_V_given_J(self, CDR3_seq, V_usage_mask, J_usage_mask):
        """Compute Pi_V conditioned on J.
    
        This function returns the Pi array from the model factors of the V genomic 
        contributions, P(V, J)*P(delV|V). This corresponds to V(J)_{x_1}.
        
        For clarity in parsing the algorithm implementation, we include which 
        instance attributes are used in the method as 'parameters.'
    
        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
            
        self.cutV_genomic_CDR3_segs : list of strings
            List of all the V genomic nucleotide sequences trimmed to begin at the 
            conserved C residue and with the maximum number of palindromic 
            insertions appended.
        self.PVdelV_nt_pos_vec : list of ndarrays
            For each V allele, format P(delV|V) into the correct form for a Pi 
            array or V(J)_{x_1}. This is only done for the first and last 
            position in each codon.    
        self.PVdelV_2nd_nt_pos_per_aa_vec : list of dicts
            For each V allele, and each 'amino acid', format P(V)*P(delV|V) for 
            positions in the middle of a codon into the correct form for a Pi 
            array or V(J)_{x_1} given the 'amino acid'.
        self.PVJ : ndarray
            Joint probability distribution of V and J, P(V, J).
    
        Returns
        -------
        Pi_V_given_J : list
            List of (4, 3L) ndarrays corresponding to V(J)_{x_1}.
        max_V_align: int
            Maximum alignment of the CDR3_seq to any genomic V allele allowed by
            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_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)