def logpdf_joint(self, bdb, generator_id, targets, constraints,
            modelno=None):
        M_c = self._crosscat_metadata(bdb, generator_id)
        try:
            for _, colno, value in constraints:
                crosscat_value_to_code(bdb, generator_id, M_c, colno, value)
        except KeyError:
            # Probability with constraint that has no code
            return float('nan')
        try:
            for _, colno, value in targets:
                crosscat_value_to_code(bdb, generator_id, M_c, colno, value)
        except __HOLE__:
            # Probability of value that has no code
            return float('-inf')
        X_L_list = self._crosscat_latent_state(bdb, generator_id, modelno)
        X_D_list = self._crosscat_latent_data(bdb, generator_id, modelno)
        Q, Y, X_L_list, X_D_list = self._crosscat_remap_two(
            bdb, generator_id, X_L_list, X_D_list, targets, constraints)
        r = self._crosscat.predictive_probability_multistate(
            M_c=M_c,
            X_L_list=X_L_list,
            X_D_list=X_D_list,
            Y=Y,
            Q=Q,
        )
        return r
dataset/ETHPy150Open probcomp/bayeslite/src/metamodels/crosscat.py/CrosscatMetamodel.logpdf_joint