public StructEmBayesSearchRunner(
      DataWrapper dataWrapper, BayesPmWrapper bayesPmWrapper, StructEmBayesSearchParams params) {
    if (dataWrapper == null) {
      throw new NullPointerException();
    }

    if (bayesPmWrapper == null) {
      throw new NullPointerException();
    }

    if (params == null) {
      throw new NullPointerException();
    }

    DataSet dataSet = (DataSet) dataWrapper.getSelectedDataModel();

    FactoredBayesStructuralEM estimator =
        new FactoredBayesStructuralEM(dataSet, bayesPmWrapper.getBayesPm());
    this.dataSet = estimator.getDataSet();

    try {
      this.estimatedBayesIm = estimator.maximization(params.getTolerance());

    } catch (IllegalArgumentException e) {
      throw new RuntimeException(e);
    }
  }
  private void estimate(DataSet DataSet, BayesPm bayesPm) {
    double thresh = 0.0001;

    //        for (Iterator i = graph.getNodes().iterator(); i.hasNext();) {
    //            Node node = (Node) i.next();
    //            if (node.getNodeType() == NodeType.LATENT) {
    //                throw new IllegalArgumentException("Estimation of Bayes IM's " +
    //                        "with latents is not supported.");
    //            }
    //        }

    try {
      FactoredBayesStructuralEM estimator = new FactoredBayesStructuralEM(DataSet, bayesPm);
      this.dataSet = estimator.getDataSet();
      this.estimatedBayesIm = estimator.maximization(thresh);
    } catch (ArrayIndexOutOfBoundsException e) {
      e.printStackTrace();
      throw new RuntimeException(
          "Value assignments between Bayes PM " + "and discrete data set do not match.");
    }
  }