<commit_before>package org.biojava.bio.structure.quaternary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.biojava.bio.structure.Atom;
import org.biojava.bio.structure.AtomImpl;
import org.biojava.bio.structure.Calc;
import org.biojava.bio.structure.Chain;
import org.biojava.bio.structure.Group;
import org.biojava.bio.structure.Structure;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructAssembly;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructAssemblyGen;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructOperList;
import org.biojava.bio.structure.jama.Matrix;



/** Reconstructs the quaternary structure of a protein from an asymmetric unit
 * 
 * @author <NAME>
 * @author <NAME>
 *
 */
public class BiologicalAssemblyBuilder {

	OperatorResolver operatorResolver;

	String asymId ;

	PdbxStructAssembly psa;
	List<PdbxStructAssemblyGen> psags;
	//List<PdbxStructOperList> operators;

	List<ModelTransformationMatrix> modelTransformations;

	//List<String> asymIds;
	public BiologicalAssemblyBuilder(){
		init();
	}

	private void init(){
		operatorResolver= new OperatorResolver();
		modelTransformations = new ArrayList<ModelTransformationMatrix>(1);
		
	}




	public Structure rebuildQuaternaryStructure(Structure asymUnit, List<ModelTransformationMatrix> transformations){

		Structure s = asymUnit.clone();
		List<Chain> transformedChains = new ArrayList<Chain>();
		//System.out.print("rebuilding " + s.getPDBCode() + " ");
		//for (Chain c : s.getChains()) {
			//System.out.print(c.getChainID());
			//if ( c.getInternalChainID() != null) {
				//System.out.print("("+c.getInternalChainID()+")");
			//}

		//}

		//asymUnit.getPDBHeader().setBioUnitTranformations(transformations);


		//double[] tmpcoords = new double[3]; 
		for (ModelTransformationMatrix max : transformations){
			boolean foundChain = false;
			for ( Chain c : s.getChains()){

				String intChainID = c.getInternalChainID();
				if ( intChainID == null) {
					//System.err.println("no internal chain ID found, using " + c.getChainID() + " ( while looking for " + max.ndbChainId+")");
					intChainID = c.getChainID();
				}

				if ( max.ndbChainId.equals(intChainID)){

					/*System.out.println("transforming " + max.ndbChainId + " " + c.getChainID());
					System.out.println(max );
					System.out.println();
					 */
					foundChain = true;
					Chain newChain = (Chain)c.clone();
					Matrix m = max.getMatrix();
					//m = m.transpose();
					double[] vector = max.getVector();
					Atom v = new AtomImpl();
					v.setCoords(vector);
					for ( Group g :newChain.getAtomGroups()) {
						for ( Atom a : g.getAtoms()) {
							//max.transformPoint(a.getCoords(), tmpcoords);
							//a.setX(tmpcoords[0]);
							//a.setY(tmpcoords[1]);
							//a.setZ(tmpcoords[2]);
							Calc.rotate(a, m);
							Calc.shift(a, v);
						}
					}

					transformedChains.add(newChain);
				}								
			}
			if (! foundChain){
				//System.err.println("could not transform chain: " + max.ndbChainId);
			}
		}

		s.setChains(transformedChains);
		return s;


	}


	/**
	 * Returns a list of transformation matrices for the generation of a macromolecular
	 * assembly for the specified assembly Id. 
	 * 
	 * @param assemblyId Id of the macromolecular assembly to be generated
	 * @return list of transformation matrices to generate macromolecular assembly
	 */
	public ArrayList<ModelTransformationMatrix> getBioUnitTransformationList(PdbxStructAssembly psa, List<PdbxStructAssemblyGen> psags, List<PdbxStructOperList> operators) {

		//System.out.println("Rebuilding " + psa.getDetails() + " | " + psa.getOligomeric_details() + " | " + psa.getOligomeric_count());
		//System.out.println(psag);<commit_msg>making sure that multiple copies of the same chain are in different models<commit_after>package org.biojava.bio.structure.quaternary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.biojava.bio.structure.Atom;
import org.biojava.bio.structure.AtomImpl;
import org.biojava.bio.structure.Calc;
import org.biojava.bio.structure.Chain;
import org.biojava.bio.structure.Group;
import org.biojava.bio.structure.Structure;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructAssembly;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructAssemblyGen;
import org.biojava.bio.structure.io.mmcif.model.PdbxStructOperList;
import org.biojava.bio.structure.jama.Matrix;



/** Reconstructs the quaternary structure of a protein from an asymmetric unit
 * 
 * @author <NAME>
 * @author <NAME>
 *
 */
public class BiologicalAssemblyBuilder {

	OperatorResolver operatorResolver;

	String asymId ;

	PdbxStructAssembly psa;
	List<PdbxStructAssemblyGen> psags;
	//List<PdbxStructOperList> operators;

	List<ModelTransformationMatrix> modelTransformations;

	//List<String> asymIds;
	public BiologicalAssemblyBuilder(){
		init();
	}

	private void init(){
		operatorResolver= new OperatorResolver();
		modelTransformations = new ArrayList<ModelTransformationMatrix>(1);
		
	}




	public Structure rebuildQuaternaryStructure(Structure asymUnit, List<ModelTransformationMatrix> transformations){

		Structure s = asymUnit.clone();
		List<Chain> transformedChains = new ArrayList<Chain>();
		s.setChains(transformedChains);
		//System.out.print("rebuilding " + s.getPDBCode() + " ");
		//for (Chain c : s.getChains()) {
			//System.out.print(c.getChainID());
			//if ( c.getInternalChainID() != null) {
				//System.out.print("("+c.getInternalChainID()+")");
			//}

		//}

		//asymUnit.getPDBHeader().setBioUnitTranformations(transformations);


		//double[] tmpcoords = new double[3]; 
		for (ModelTransformationMatrix max : transformations){
			boolean foundChain = false;
			for ( Chain c : asymUnit.getChains()){

				String intChainID = c.getInternalChainID();
				if ( intChainID == null) {
					//System.err.println("no internal chain ID found, using " + c.getChainID() + " ( while looking for " + max.ndbChainId+")");
					intChainID = c.getChainID();
				}

				if ( max.ndbChainId.equals(intChainID)){

					/*System.out.println("transforming " + max.ndbChainId + " " + c.getChainID());
					System.out.println(max );
					System.out.println();
					 */
					foundChain = true;
					Chain newChain = (Chain)c.clone();
					Matrix m = max.getMatrix();
					//m = m.transpose();
					double[] vector = max.getVector();
					Atom v = new AtomImpl();
					v.setCoords(vector);
					for ( Group g :newChain.getAtomGroups()) {
						for ( Atom a : g.getAtoms()) {
							//max.transformPoint(a.getCoords(), tmpcoords);
							//a.setX(tmpcoords[0]);
							//a.setY(tmpcoords[1]);
							//a.setZ(tmpcoords[2]);
							Calc.rotate(a, m);
							Calc.shift(a, v);
						}
					}

					
					addCheckChainModel(s,newChain);

				}								
			}
			if (! foundChain){
				//System.err.println("could not transform chain: " + max.ndbChainId);
			}
		}

		//s.setChains(transformedChains);
		return s;


	}


	private void addCheckChainModel(Structure s, Chain newChain) {
		for ( int i = 0 ; i < s.nrModels() ; i ++){
			List<Chain> model = s.getModel(i);
			boolean found = false;
			for ( Chain c : model){
				if ( c.getChainID().equals(newChain.getChainID())) {
					found = true;
					break;
				}
			}
			if ( ! found){
			
				model.add(newChain);
				return;
			}
			
		}
		
		// all existing models contain already a chain with the same ID. add a new model
		List<Chain> newModel = new ArrayList<Chain>();
		newModel.add(newChain);
		s.addModel(newModel);
		
	}

	/**
	 * Returns a list of transformation matrices for the generation of a macromolecular
	 * assembly for the specified assembly Id. 
	 * 
	 * @param assemblyId Id of the macromolecular assembly to be generated
	 * @return list of transformation matrices to generate macromolecular assembly
	 */
	public ArrayList<ModelTransformationMatrix> getBioUnitTransformationList(PdbxStructAssembly psa, List<PdbxStructAssemblyGen> psags, List<PdbxStructOperList> operators) {

		//System.out.println("Rebuilding " + psa.getDetails() + " | " + psa.getOligomeric_details() + " | " + psa.getOligomeric_count());
		//System.out.println(psag);
{'fraction_non_alphanumeric': 0.13555392874572963, 'fraction_numerical': 0.0013421181063933627, 'mean_word_length': 3.6653386454183265, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5017562', 'n_tokens_mistral': 3110, 'n_tokens_neox': 2590, 'n_words': 533}