public void calcAsas(int nSpherePoints, int nThreads, int cofactorSizeToUse) {

		// asa/bsa calculation
		// NOTE in principle it is more efficient to calculate asas only once per unique chain
		// BUT! the rolling ball algorithm gives slightly different values for same molecule in different
		// rotations (due to sampling depending on orientation of axes grid).
		// Both NACCESS and our own implementation behave like that.
		// That's why we calculate ASAs for each rotation-unique molecule, otherwise
		// we get discrepancies (not very big but annoying) which lead to things like negative (small) bsa values


		Map<String, Atom[]> uniqAsaChains = new TreeMap<>();
		Map<String, double[]> chainAsas = new TreeMap<>();

		List<StructureInterface> redundancyReducedList;
		if (clustersNcs != null) {
			redundancyReducedList = new ArrayList<>();
			for (StructureInterfaceCluster ncsCluster : clustersNcs) {
				// we use the first one in list as the only one for which we calculate ASAs
				redundancyReducedList.add(ncsCluster.getMembers().get(0));
			}

		} else {
			redundancyReducedList = list;
		}

		// first we gather rotation-unique chains (in terms of AU id and transform id)
		for (StructureInterface interf:redundancyReducedList) {
			String molecId1 = interf.getMoleculeIds().getFirst()+interf.getTransforms().getFirst().getTransformId();
			String molecId2 = interf.getMoleculeIds().getSecond()+interf.getTransforms().getSecond().getTransformId();

			uniqAsaChains.put(molecId1, interf.getFirstAtomsForAsa(cofactorSizeToUse));
			uniqAsaChains.put(molecId2, interf.getSecondAtomsForAsa(cofactorSizeToUse));
		}

		logger.debug("Will calculate uncomplexed ASA for {} orientation-unique chains.", uniqAsaChains.size());

		long start = System.currentTimeMillis();

		// we only need to calculate ASA for that subset (any translation of those will have same values)
		for (String molecId:uniqAsaChains.keySet()) {

			logger.debug("Calculating uncomplexed ASA for molecId {}, with {} atoms", molecId, uniqAsaChains.get(molecId).length);

			AsaCalculator asaCalc = new AsaCalculator(uniqAsaChains.get(molecId),
					AsaCalculator.DEFAULT_PROBE_SIZE, nSpherePoints, nThreads);

			double[] atomAsas = asaCalc.calculateAsas();

			chainAsas.put(molecId, atomAsas);

		}
		long end = System.currentTimeMillis();

		logger.debug("Calculated uncomplexed ASA for {} orientation-unique chains. Time: {} s", uniqAsaChains.size(), ((end-start)/1000.0));

		logger.debug ("Will calculate complexed ASA for {} pairwise complexes.", redundancyReducedList.size());

		start = System.currentTimeMillis();

		// now we calculate the ASAs for each of the complexes
		for (StructureInterface interf:redundancyReducedList) {

			String molecId1 = interf.getMoleculeIds().getFirst()+interf.getTransforms().getFirst().getTransformId();
			String molecId2 = interf.getMoleculeIds().getSecond()+interf.getTransforms().getSecond().getTransformId();

			logger.debug("Calculating complexed ASAs for interface {} between molecules {} and {}", interf.getId(), molecId1, molecId2);

			interf.setAsas(chainAsas.get(molecId1), chainAsas.get(molecId2), nSpherePoints, nThreads, cofactorSizeToUse);

		}
		end = System.currentTimeMillis();

		logger.debug("Calculated complexes ASA for {} pairwise complexes. Time: {} s", redundancyReducedList.size(), ((end-start)/1000.0));

		// now let's populate the interface area value for the NCS-redundant ones from the reference interface (first one in list)
		if (clustersNcs!=null) {
			if (chainOrigNamesMap==null)  {
				logger.warn("No chainOrigNamesMap is set. Considering NCS interfaces in same order as reference. This is likely a bug.");
			}
			for (StructureInterfaceCluster ncsCluster : clustersNcs) {
				StructureInterface refInterf = ncsCluster.getMembers().get(0);
				String refMolecId1 = refInterf.getMoleculeIds().getFirst();
				for (int i=1;i<ncsCluster.getMembers().size();i++) {
					StructureInterface member = ncsCluster.getMembers().get(i);
					member.setTotalArea(refInterf.getTotalArea());
					String molecId1 = member.getMoleculeIds().getFirst();
					if (areMolecIdsSameOrder(refMolecId1, molecId1)) {
						// we add the reference interface GroupAsas as the GroupAsas for all other members, like that
						// ResidueNumbers won't match in their chain ids, but otherwise all info is there without using a lot of memory
						member.setFirstGroupAsas(refInterf.getFirstGroupAsas());
						member.setSecondGroupAsas(refInterf.getSecondGroupAsas());
					} else {
						member.setFirstGroupAsas(refInterf.getSecondGroupAsas());
						member.setSecondGroupAsas(refInterf.getFirstGroupAsas());
					}
				}
			}
		}

		// finally we sort based on the ChainInterface.comparable() (based in interfaceArea)
		sort();
	}
public void calcAsas ( int nSpherePoints , int nThreads , int cofactorSizeToUse ) { Map < String , Atom [ ] > uniqAsaChains = new TreeMap < > ( ) ; Map < String , double [ ] > chainAsas = new TreeMap < > ( ) ; List < StructureInterface > redundancyReducedList ; if ( clustersNcs != null ) { redundancyReducedList = new ArrayList < > ( ) ; for ( StructureInterfaceCluster ncsCluster : clustersNcs ) { redundancyReducedList . add ( ncsCluster . getMembers ( ) . get ( 0 ) ) ; } } else { redundancyReducedList = list ; } for ( StructureInterface interf : redundancyReducedList ) { String molecId1 = interf . getMoleculeIds ( ) . getFirst ( ) + interf . getTransforms ( ) . getFirst ( ) . getTransformId ( ) ; String molecId2 = interf . getMoleculeIds ( ) . getSecond ( ) + interf . getTransforms ( ) . getSecond ( ) . getTransformId ( ) ; uniqAsaChains . put ( molecId1 , interf . getFirstAtomsForAsa ( cofactorSizeToUse ) ) ; uniqAsaChains . put ( molecId2 , interf . getSecondAtomsForAsa ( cofactorSizeToUse ) ) ; } logger . debug ( "Will calculate uncomplexed ASA for {} orientation-unique chains." , uniqAsaChains . size ( ) ) ; long start = System . currentTimeMillis ( ) ; for ( String molecId : uniqAsaChains . keySet ( ) ) { logger . debug ( "Calculating uncomplexed ASA for molecId {}, with {} atoms" , molecId , uniqAsaChains . get ( molecId ) . length ) ; AsaCalculator asaCalc = new AsaCalculator ( uniqAsaChains . get ( molecId ) , AsaCalculator . DEFAULT_PROBE_SIZE , nSpherePoints , nThreads ) ; double [ ] atomAsas = asaCalc . calculateAsas ( ) ; chainAsas . put ( molecId , atomAsas ) ; } long end = System . currentTimeMillis ( ) ; logger . debug ( "Calculated uncomplexed ASA for {} orientation-unique chains. Time: {} s" , uniqAsaChains . size ( ) , ( ( end - start ) / 1000.0 ) ) ; logger . debug ( "Will calculate complexed ASA for {} pairwise complexes." , redundancyReducedList . size ( ) ) ; start = System . currentTimeMillis ( ) ; for ( StructureInterface interf : redundancyReducedList ) { String molecId1 = interf . getMoleculeIds ( ) . getFirst ( ) + interf . getTransforms ( ) . getFirst ( ) . getTransformId ( ) ; String molecId2 = interf . getMoleculeIds ( ) . getSecond ( ) + interf . getTransforms ( ) . getSecond ( ) . getTransformId ( ) ; logger . debug ( "Calculating complexed ASAs for interface {} between molecules {} and {}" , interf . getId ( ) , molecId1 , molecId2 ) ; interf . setAsas ( chainAsas . get ( molecId1 ) , chainAsas . get ( molecId2 ) , nSpherePoints , nThreads , cofactorSizeToUse ) ; } end = System . currentTimeMillis ( ) ; logger . debug ( "Calculated complexes ASA for {} pairwise complexes. Time: {} s" , redundancyReducedList . size ( ) , ( ( end - start ) / 1000.0 ) ) ; if ( clustersNcs != null ) { if ( chainOrigNamesMap == null ) { logger . warn ( "No chainOrigNamesMap is set. Considering NCS interfaces in same order as reference. This is likely a bug." ) ; } for ( StructureInterfaceCluster ncsCluster : clustersNcs ) { StructureInterface refInterf = ncsCluster . getMembers ( ) . get ( 0 ) ; String refMolecId1 = refInterf . getMoleculeIds ( ) . getFirst ( ) ; for ( int i = 1 ; i < ncsCluster . getMembers ( ) . size ( ) ; i ++ ) { StructureInterface member = ncsCluster . getMembers ( ) . get ( i ) ; member . setTotalArea ( refInterf . getTotalArea ( ) ) ; String molecId1 = member . getMoleculeIds ( ) . getFirst ( ) ; if ( areMolecIdsSameOrder ( refMolecId1 , molecId1 ) ) { member . setFirstGroupAsas ( refInterf . getFirstGroupAsas ( ) ) ; member . setSecondGroupAsas ( refInterf . getSecondGroupAsas ( ) ) ; } else { member . setFirstGroupAsas ( refInterf . getSecondGroupAsas ( ) ) ; member . setSecondGroupAsas ( refInterf . getFirstGroupAsas ( ) ) ; } } } } sort ( ) ; }
Calculates ASAs for all interfaces in list, both for the unbound
chains and for the complex of the two chains together.
Also sorts the interfaces based on calculated BSA areas (descending)
@param nSpherePoints
@param nThreads
@param cofactorSizeToUse the minimum size of cofactor molecule (non-chain HET atoms) that will be used