<commit_before>package org.rcsb.mmtf.decoder;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.rcsb.mmtf.api.DataApiInterface;
import org.rcsb.mmtf.api.StructureDecoderInterface;
import org.rcsb.mmtf.dataholders.Entity;
import org.rcsb.mmtf.dataholders.PDBGroup;

/**
 * Decode an MMTF structure using a structure inflator. The class also allows access to the unconsumed but parsed and inflated underlying data.
 * 
 * @author <NAME>
 *
 */
public class DecodeStructure {

	

	/** The struct inflator. */
	private StructureDecoderInterface structInflator;

	/** The api to the data */
	private DataApiInterface dataApi;
	
	/* 
	 * Initialise the counters
	 */
	private int modelCounter = 0;
	private int chainCounter = 0;
	private int groupCounter = 0;
	private int atomCounter = 0;
	private int lastAtomCount = 0;
	private Set<String> chainIdSet;
	private String[] chainList;

	/**
	 * The constructor requires a byte array to fill the data. This will decompress the arrays using our bespoke methods.
	 * @param inputByteArr An unentropy encoded byte array with the data as found in the MMTF format
	 */
	public DecodeStructure(byte[] inputByteArr) {

		// Data api
		dataApi = new SimpleDataApi(inputByteArr);

	}


	/**
	 * Generate a structure from bytes using a structure inflator.
	 *
	 * @param myInBytes the my in bytes
	 * @param inputStructInflator the input struct inflator
	 * @param parsingParams the parsing params
	 */
	public final void getStructFromByteArray(final StructureDecoderInterface inputStructInflator, final ParsingParams parsingParams) {    
		// Set the inflator
		structInflator = inputStructInflator;
		// Do any required preparation
		inputStructInflator.prepareStructure(dataApi.getNumAtoms(), dataApi.getNumResidues(),
				dataApi.getNumChains(), dataApi.getNumModels());
		// Now get the parsing parameters to do their thing
		useParseParams(parsingParams);
		// Now get the group map
		for (int modelChains: dataApi.getChainsPerModel()) {
			structInflator.setModelInfo(modelCounter, modelChains);
			// A list to check if we need to set or update the chains
			chainIdSet = new HashSet<>();
			int totChainsThisModel = chainCounter + modelChains;
			for (int chainIndex = chainCounter; chainIndex < totChainsThisModel;  chainIndex++) {
				addOrUpdateChainInfo(chainIndex);
			}
			modelCounter++;
		}
		// Now add the header information.
		addHeaderInfo();
		// Now set the crystallographic  information
		addXtalographicInfo();
		/// Now get the bioassembly information
		generateBioAssembly();
		// Now add the other bonds between groups
		addInterGroupBonds();
		for (Entity entity : dataApi.getEntityList()) {
			String[] chainIdList = new String[entity.getChainIndexList().length];
			int counter = 0;
			for (int chainInd : entity.getChainIndexList()) {
				chainIdList[counter] = chainList[chainInd];
				counter++;
			}
			inputStructInflator.setEntityInfo(chainIdList, entity.getSequence(), entity.getDescription(), entity.getType());
		}
		
		
		// Now do any required cleanup
		inputStructInflator.cleanUpStructure();
	}

	/**
	 * Function to add ancilliary header information to the structure
	 */
	private void addHeaderInfo() {
		structInflator.setHeaderInfo(dataApi.getRfree(),dataApi.getRwork(), dataApi.getResolution(), dataApi.getTitle(), dataApi.getExperimentalMethods());		
	}


	/**
	 * Use the parsing parameters to set the scene.
	 * @param parsingParams
	 */
	private void useParseParams(ParsingParams parsingParams) {
		if (parsingParams.isParseInternal()) {
			System.out.println("Using asym ids");
			chainList = dataApi.getChainIds();
		} else {
			System.out.println("Using auth ids");
			chainList = dataApi.getChainNames();
		}    
	}


	/**<commit_msg>Refactor and reorganise the decode structur function<commit_after>package org.rcsb.mmtf.decoder;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.rcsb.mmtf.api.DataApiInterface;
import org.rcsb.mmtf.api.StructureDecoderInterface;
import org.rcsb.mmtf.dataholders.Entity;
import org.rcsb.mmtf.dataholders.PDBGroup;

/**
 * Decode an MMTF structure using a structure inflator. The class also allows access to the unconsumed but parsed and inflated underlying data.
 * 
 * @author <NAME>
 *
 */
public class DecodeStructure {

	

	/** The struct inflator. */
	private StructureDecoderInterface structInflator;

	/** The api to the data */
	private DataApiInterface dataApi;
	
	/* 
	 * Initialise the counters
	 */
	private int modelCounter = 0;
	private int chainCounter = 0;
	private int groupCounter = 0;
	private int atomCounter = 0;
	private int lastAtomCount = 0;
	private Set<String> chainIdSet;
	private String[] chainList;

	/**
	 * The constructor requires a byte array to fill the data. This will decompress the arrays using our bespoke methods.
	 * @param inputByteArr An unentropy encoded byte array with the data as found in the MMTF format
	 */
	public DecodeStructure(byte[] inputByteArr) {

		// Data api
		dataApi = new SimpleDataApi(inputByteArr);

	}


	/**
	 * Generate a structure from bytes using a structure inflator.
	 *
	 * @param myInBytes the my in bytes
	 * @param inputStructInflator the input struct inflator
	 * @param parsingParams the parsing params
	 */
	public final void getStructFromByteArray(final StructureDecoderInterface inputStructInflator, final ParsingParams parsingParams) {    
		// Set the inflator
		structInflator = inputStructInflator;
		// Do any required preparation
		inputStructInflator.prepareStructure(dataApi.getNumAtoms(), dataApi.getNumResidues(), dataApi.getNumChains(), dataApi.getNumModels());
		// Now get the parsing parameters to do their thing
		useParseParams(parsingParams);
		// Now add the atom information
		addAtomicInformation();
		// Now add the header information.
		addHeaderInfo();
		// Now set the crystallographic  information
		addXtalographicInfo();
		/// Now get the bioassembly information
		generateBioAssembly();
		// Now add the other bonds between groups
		addInterGroupBonds();
		// Now add the entity info
		addEntityInfo();
		// Now do any required cleanup
		structInflator.cleanUpStructure();
	}
	
	/**
	 * Add the main atomic information to the data model
	 */
	private void addAtomicInformation() {
		for (int modelChains: dataApi.getChainsPerModel()) {
			structInflator.setModelInfo(modelCounter, modelChains);
			// A list to check if we need to set or update the chains
			chainIdSet = new HashSet<>();
			int totChainsThisModel = chainCounter + modelChains;
			for (int chainIndex = chainCounter; chainIndex < totChainsThisModel;  chainIndex++) {
				addOrUpdateChainInfo(chainIndex);
			}
			modelCounter++;
		}		
	}


	/**
	 * Add the entity information to a structure.
	 */
	private void addEntityInfo() {
		for (Entity entity : dataApi.getEntityList()) {
			String[] chainIdList = new String[entity.getChainIndexList().length];
			int counter = 0;
			for (int chainInd : entity.getChainIndexList()) {
				chainIdList[counter] = chainList[chainInd];
				counter++;
			}
			structInflator.setEntityInfo(chainIdList, entity.getSequence(), entity.getDescription(), entity.getType());
		}		
	}


	/**
	 * Function to add ancilliary header information to the structure
	 */
	private void addHeaderInfo() {
		structInflator.setHeaderInfo(dataApi.getRfree(),dataApi.getRwork(), dataApi.getResolution(), dataApi.getTitle(), dataApi.getExperimentalMethods());		
	}


	/**
	 * Use the parsing parameters to set the scene.
	 * @param parsingParams
	 */
	private void useParseParams(ParsingParams parsingParams) {
		if (parsingParams.isParseInternal()) {
			System.out.println("Using asym ids");
			chainList = dataApi.getChainIds();
		} else {
			System.out.println("Using auth ids");
			chainList = dataApi.getChainNames();
		}    
	}


	/**
{'fraction_non_alphanumeric': 0.09602352640327323, 'fraction_numerical': 0.0015343306482546988, 'mean_word_length': 4.11576193590582, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, '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': '1919365', 'n_tokens_mistral': 2521, 'n_tokens_neox': 2220, 'n_words': 683}