public static Group[] prepareGroupsForDisplay(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException{


		if ( afpChain.getBlockRotationMatrix().length == 0 ) {
			// probably the alignment is too short!
			System.err.println("No rotation matrix found to rotate 2nd structure!");
			afpChain.setBlockRotationMatrix(new Matrix[]{Matrix.identity(3, 3)});
			afpChain.setBlockShiftVector(new Atom[]{new AtomImpl()});
		}

		// List of groups to be rotated according to the alignment
		Group[] twistedGroups = new Group[ ca2.length];

		//int blockNum = afpChain.getBlockNum();

		int i = -1;

		// List of groups from the structure not included in ca2 (e.g. ligands)
		// Will be rotated according to first block
		List<Group> hetatms2 = StructureTools.getUnalignedGroups(ca2);

		if (  (afpChain.getAlgorithmName().equals(FatCatRigid.algorithmName) ) || (afpChain.getAlgorithmName().equals(FatCatFlexible.algorithmName) ) ){

			for (Atom a: ca2){
				i++;
				twistedGroups[i]=a.getGroup();

			}

			twistedGroups = AFPTwister.twistOptimized(afpChain, ca1, ca2);

			//} else  if  (( blockNum == 1 ) || (afpChain.getAlgorithmName().equals(CeCPMain.algorithmName))) {
		} else {

			Matrix m   =  afpChain.getBlockRotationMatrix()[ 0];
			Atom shift =  afpChain.getBlockShiftVector()   [ 0 ];

			shiftCA2(afpChain, ca2, m,shift, twistedGroups);

		}

		if ( afpChain.getBlockNum() > 0){

			// Superimpose ligands relative to the first block
			if( hetatms2.size() > 0 ) {

				if ( afpChain.getBlockRotationMatrix().length > 0 ) {

					Matrix m1      = afpChain.getBlockRotationMatrix()[0];
					//m1.print(3,3);
					Atom   vector1 = afpChain.getBlockShiftVector()[0];
					//System.out.println("shift vector:" + vector1);

					for ( Group g : hetatms2){
						Calc.rotate(g, m1);
						Calc.shift(g,vector1);
					}
				}
			}
		}

		return twistedGroups;
	}
public static Group [ ] prepareGroupsForDisplay ( AFPChain afpChain , Atom [ ] ca1 , Atom [ ] ca2 ) throws StructureException { if ( afpChain . getBlockRotationMatrix ( ) . length == 0 ) { System . err . println ( "No rotation matrix found to rotate 2nd structure!" ) ; afpChain . setBlockRotationMatrix ( new Matrix [ ] { Matrix . identity ( 3 , 3 ) } ) ; afpChain . setBlockShiftVector ( new Atom [ ] { new AtomImpl ( ) } ) ; } Group [ ] twistedGroups = new Group [ ca2 . length ] ; int i = - 1 ; List < Group > hetatms2 = StructureTools . getUnalignedGroups ( ca2 ) ; if ( ( afpChain . getAlgorithmName ( ) . equals ( FatCatRigid . algorithmName ) ) || ( afpChain . getAlgorithmName ( ) . equals ( FatCatFlexible . algorithmName ) ) ) { for ( Atom a : ca2 ) { i ++ ; twistedGroups [ i ] = a . getGroup ( ) ; } twistedGroups = AFPTwister . twistOptimized ( afpChain , ca1 , ca2 ) ; } else { Matrix m = afpChain . getBlockRotationMatrix ( ) [ 0 ] ; Atom shift = afpChain . getBlockShiftVector ( ) [ 0 ] ; shiftCA2 ( afpChain , ca2 , m , shift , twistedGroups ) ; } if ( afpChain . getBlockNum ( ) > 0 ) { if ( hetatms2 . size ( ) > 0 ) { if ( afpChain . getBlockRotationMatrix ( ) . length > 0 ) { Matrix m1 = afpChain . getBlockRotationMatrix ( ) [ 0 ] ; Atom vector1 = afpChain . getBlockShiftVector ( ) [ 0 ] ; for ( Group g : hetatms2 ) { Calc . rotate ( g , m1 ) ; Calc . shift ( g , vector1 ) ; } } } } return twistedGroups ; }
Rotate the Atoms/Groups so they are aligned for the 3D visualisation

@param afpChain
@param ca1
@param ca2
@return an array of Groups that are transformed for 3D display
@throws StructureException