public Structure rebuildQuaternaryStructure(Structure asymUnit, List<BiologicalAssemblyTransformation> transformations, boolean useAsymIds, boolean multiModel) {

		// ensure that new chains are build in the same order as they appear in the asymmetric unit
		orderTransformationsByChainId(asymUnit, transformations);

		Structure s = asymUnit.clone();

		Map<Integer, EntityInfo> entityInfoMap = new HashMap<>();
		// this resets all models (not only the first one): this is important for NMR (multi-model)
		// like that we can be sure we start with an empty structures and we add models or chains to it
		s.resetModels();
		s.setEntityInfos(new ArrayList<>());

		for (BiologicalAssemblyTransformation transformation : transformations){

			List<Chain> chainsToTransform = new ArrayList<>();

			// note: for NMR structures (or any multi-model) we use the first model only and throw away the rest
			if (useAsymIds) {
				Chain c = asymUnit.getChain(transformation.getChainId());
				chainsToTransform.add(c);
			} else {
				Chain polyC = asymUnit.getPolyChainByPDB(transformation.getChainId());
				List<Chain> nonPolyCs = asymUnit.getNonPolyChainsByPDB(transformation.getChainId());
				Chain waterC = asymUnit.getWaterChainByPDB(transformation.getChainId());
				if (polyC!=null)
					chainsToTransform.add(polyC);
				if (!nonPolyCs.isEmpty())
					chainsToTransform.addAll(nonPolyCs);
				if (waterC!=null)
					chainsToTransform.add(waterC);
			}

			for (Chain c: chainsToTransform) {

				Chain chain = (Chain)c.clone();

				Calc.transform(chain, transformation.getTransformationMatrix());

				String transformId = transformation.getId();

				// note that the Structure.addChain/Structure.addModel methods set the parent reference to the new Structure

				if (multiModel)
					addChainMultiModel(s, chain, transformId);
				else
					addChainFlattened(s, chain, transformId);

				EntityInfo entityInfo;
				if (!entityInfoMap.containsKey(chain.getEntityInfo().getMolId())) {
					entityInfo = new EntityInfo(chain.getEntityInfo());
					entityInfoMap.put(chain.getEntityInfo().getMolId(), entityInfo);
					s.addEntityInfo(entityInfo);
				} else {
					entityInfo = entityInfoMap.get(chain.getEntityInfo().getMolId());
				}
				chain.setEntityInfo(entityInfo);
				entityInfo.addChain(chain);

			}
		}

		s.setBiologicalAssembly(true);
		return s;
	}
public Structure rebuildQuaternaryStructure ( Structure asymUnit , List < BiologicalAssemblyTransformation > transformations , boolean useAsymIds , boolean multiModel ) { orderTransformationsByChainId ( asymUnit , transformations ) ; Structure s = asymUnit . clone ( ) ; Map < Integer , EntityInfo > entityInfoMap = new HashMap < > ( ) ; s . resetModels ( ) ; s . setEntityInfos ( new ArrayList < > ( ) ) ; for ( BiologicalAssemblyTransformation transformation : transformations ) { List < Chain > chainsToTransform = new ArrayList < > ( ) ; if ( useAsymIds ) { Chain c = asymUnit . getChain ( transformation . getChainId ( ) ) ; chainsToTransform . add ( c ) ; } else { Chain polyC = asymUnit . getPolyChainByPDB ( transformation . getChainId ( ) ) ; List < Chain > nonPolyCs = asymUnit . getNonPolyChainsByPDB ( transformation . getChainId ( ) ) ; Chain waterC = asymUnit . getWaterChainByPDB ( transformation . getChainId ( ) ) ; if ( polyC != null ) chainsToTransform . add ( polyC ) ; if ( ! nonPolyCs . isEmpty ( ) ) chainsToTransform . addAll ( nonPolyCs ) ; if ( waterC != null ) chainsToTransform . add ( waterC ) ; } for ( Chain c : chainsToTransform ) { Chain chain = ( Chain ) c . clone ( ) ; Calc . transform ( chain , transformation . getTransformationMatrix ( ) ) ; String transformId = transformation . getId ( ) ; if ( multiModel ) addChainMultiModel ( s , chain , transformId ) ; else addChainFlattened ( s , chain , transformId ) ; EntityInfo entityInfo ; if ( ! entityInfoMap . containsKey ( chain . getEntityInfo ( ) . getMolId ( ) ) ) { entityInfo = new EntityInfo ( chain . getEntityInfo ( ) ) ; entityInfoMap . put ( chain . getEntityInfo ( ) . getMolId ( ) , entityInfo ) ; s . addEntityInfo ( entityInfo ) ; } else { entityInfo = entityInfoMap . get ( chain . getEntityInfo ( ) . getMolId ( ) ) ; } chain . setEntityInfo ( entityInfo ) ; entityInfo . addChain ( chain ) ; } } s . setBiologicalAssembly ( true ) ; return s ; }
Builds a Structure object containing the quaternary structure built from given asymUnit and transformations,
by adding symmetry partners as new models.
The output Structure will be different depending on the multiModel parameter:
<li>
the symmetry-expanded chains are added as new models, one per transformId. All original models but
the first one are discarded.
</li>
<li>
as original with symmetry-expanded chains added with renamed chain ids and names (in the form
originalAsymId_transformId and originalAuthId_transformId)
</li>
@param asymUnit
@param transformations
@param useAsymIds if true use {@link Chain#getId()} to match the ids in the BiologicalAssemblyTransformation (needed if data read from mmCIF),
if false use {@link Chain#getName()} for the chain matching (needed if data read from PDB).
@param multiModel if true the output Structure will be a multi-model one with one transformId per model,
if false the outputStructure will be as the original with added chains with renamed asymIds (in the form originalAsymId_transformId and originalAuthId_transformId).
@return