content: package com.actelion.research.chem.docking.scoring;
  
  import java.util.Set;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  
  import com.actelion.research.chem.Coordinates;
  import com.actelion.research.chem.StereoMolecule;
  import com.actelion.research.chem.conf.Conformer;
  import com.actelion.research.chem.docking.LigandPose;
  import com.actelion.research.chem.io.pdb.calc.MoleculeGrid;
  import com.actelion.research.chem.potentialenergy.PotentialEnergyTerm;
  
  /**
   * this class is not thread safe!
   * @author wahljo1
   *
   */
  public abstract class AbstractScoringEngine  {
  	
  	private double BUMP_PENALTY = 500;
  	private int BUMP_RADIUS = 3;
  	
  	protected Conformer receptorConf;
  	protected Set<Integer> bindingSiteAtoms;
  	protected LigandPose candidatePose;
  	protected MoleculeGrid grid;
  	protected List<PotentialEnergyTerm> constraints;
  	
  	public AbstractScoringEngine(StereoMolecule receptor, Set<Integer> bindingSiteAtoms, MoleculeGrid grid) {
  		this.receptorConf = new Conformer(receptor);
  		this.bindingSiteAtoms = bindingSiteAtoms;
  		this.grid = grid;
  		constraints = new ArrayList<>();
  	}
  	
  	public LigandPose getCandidatePose() {
  		return candidatePose; 
  	}
  	
  
  	
  	public double getBumpTerm() {
  		double bumpTerm = 0.0;
  		int[] gridSize = grid.getGridSize();
  		for(int a=0;a<candidatePose.getLigConf().getMolecule().getAllAtoms();a++) {
  			Coordinates c = candidatePose.getLigConf().getCoordinates(a);
  			int[] gridC = grid.getGridCoordinates(c);
  			int x = gridC[0];
  			int y = gridC[1];
  			int z = gridC[2];	
  			if(x<BUMP_RADIUS || x>(gridSize[0]-BUMP_RADIUS)) {
  				bumpTerm = BUMP_PENALTY;
  				break;
  			}
  			else if(y<BUMP_RADIUS || y>(gridSize[1]-BUMP_RADIUS)) {
  				bumpTerm = BUMP_PENALTY;
  				break;
  			}
  			else if(z<BUMP_RADIUS || z>(gridSize[2]-BUMP_RADIUS)) {
  				bumpTerm = BUMP_PENALTY;
  				break;	
  				}
  			}
  		return bumpTerm;
  		}
  	
  	public void addConstraint(PotentialEnergyTerm constraint) {
  		this.constraints.add(constraint);
  	}
  	
  	public void removeConstraints() {
  		this.constraints = new ArrayList<>();
  	}
  
  	public abstract void init(LigandPose candidatePose, double e0);
  	
  	public abstract void updateState();
  
  	public abstract double getFGValue(double[] grad);
  	
  	public abstract double getScore();
  	
  	public abstract Map<String,Double> getContributions();
  
  	public Conformer getReceptorConf() {
  		return receptorConf;
  	}
  	
  	
  	
  
  }
  