code: def compute_propensity_score(
      X,
      treatment,
      p_model=None,
      X_pred=None,
      treatment_pred=None,
      calibrate_p=True,
  ):
      """Generate propensity score if user didn't provide
  
      Args:
          X (np.matrix): features for training
          treatment (np.array or pd.Series): a treatment vector for training
          p_model (propensity model object, optional):
              ElasticNetPropensityModel (default) / GradientBoostedPropensityModel
          X_pred (np.matrix, optional): features for prediction
          treatment_pred (np.array or pd.Series, optional): a treatment vector for prediciton
          calibrate_p (bool, optional): whether calibrate the propensity score
  
      Returns:
          (tuple)
              - p (numpy.ndarray): propensity score
              - p_model (PropensityModel): a trained PropensityModel object
      """
      if treatment_pred is None:
          treatment_pred = treatment.copy()
      if p_model is None:
          p_model = ElasticNetPropensityModel()
  
      p_model.fit(X, treatment)
  
      if X_pred is None:
          p = p_model.predict(X)
      else:
          p = p_model.predict(X_pred)
  
      if calibrate_p:
          logger.info("Calibrating propensity scores.")
          p = calibrate(p, treatment_pred)
  
      # force the p values within the range
      eps = np.finfo(float).eps
      p = np.where(p < 0 + eps, 0 + eps * 1.001, p)
      p = np.where(p > 1 - eps, 1 - eps * 1.001, p)
  
      return p, p_model
  
imports: from abc import ABCMeta, abstractmethod
  import logging
  import numpy
  from pygam import LogisticGAM, s
  from sklearn.metrics import roc_auc_score
  from sklearn.linear_model import LogisticRegressionCV
  from sklearn.model_selection import StratifiedKFold, train_test_split
  import xgboost
label_desc: Use image node_id 2 for calling a global function with example usage: compute_propensity_score(X, treatment, p_model, X_pred, treatment_pred, calibrate_p) and returns: p,  p_model