def compute_Pi_J(self, CDR3_seq, J_usage_mask):
        """Compute Pi_J.
    
        This function returns the Pi array from the model factors of the J genomic 
        contributions, P(delJ|J). This corresponds to J(D)^{x_4}.
        
        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).
        J_usage_mask : list
            Indices of the J alleles to be considered in the Pgen computation
        
        self.cutJ_genomic_CDR3_segs : list of strings
            List of all the J genomic nucleotide sequences trimmed to begin at the 
            conserved 3' residue (F/W) and with the maximum number of palindromic 
            insertions appended.
        self.PJdelJ_nt_pos_vec : list of ndarrays
            For each J allele, format P(delJ|J) into the correct form for a Pi 
            array or J^{x_2}. This is only done for the first and last position 
            in each codon.    
        self.PJdelJ_2nd_nt_pos_per_aa_vec : list of dicts
            For each J allele, and each 'amino acid', format P(delJ|J) for 
            positions in the middle of a codon into the correct form for a Pi 
            array or J^{x_2} given the 'amino acid'.
        
        Returns
        -------
        Pi_J : ndarray
            (4, 3L) array corresponding to J^{x_4}.
        r_J_usage_mask: list
            Reduced J_usage mask. J genes/alleles with no contribution (bad 
            alignment) are removed from the mask. This is done to speed up the 
            computation on the V side (which must be done conditioned on the J).
        
        """
        #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