private static  void mergeBlock(FatCatParameters params, AFPChain afpChain,Atom[] ca1,Atom[] ca2)
	{

		int blockNum = afpChain.getBlockNum();
		double badRmsd = params.getBadRmsd();

		int[] block2Afp = afpChain.getBlock2Afp();
		int[] blockSize = afpChain.getBlockSize();

		double[] blockRmsd = afpChain.getBlockRmsd();

		int afpChainTwiNum = afpChain.getAfpChainTwiNum();

		//clustering the neighbor blocks if their transformations are similar
		int     i, j, b1, b2, minb1, minb2;
		double  minrmsd;
		int     merge = 0;
		int     blockNumOld = blockNum;
		double[][]  rmsdlist = null;
		if(blockNum > 1)        {
			rmsdlist = new double[blockNumOld][blockNumOld];
			for(b1 = 0; b1 < blockNum - 1; b1 ++)   {
				for(b2 = b1 + 1; b2 < blockNum; b2 ++)  {
					rmsdlist[b1][b2] = combineRmsd(b1, b2,afpChain,ca1,ca2);
				}
			}
		}
		minb1 = 0;
		while(blockNum > 1)     {
			minrmsd = 1000;
			for(i = 0; i < blockNum - 1; i ++)      {
				j = i + 1; //only consider neighbor blocks
				if(minrmsd > rmsdlist[i][j])    {
					minrmsd = rmsdlist[i][j];
					minb1 = i;
				}
			}
			minb2 = minb1 + 1; //merge those most similar blocks
			//maxrmsd = (blockRmsd[minb1] > blockRmsd[minb2])?blockRmsd[minb1]:blockRmsd[minb2];
			if(minrmsd < badRmsd)   {
				if(debug)
					System.out.println(String.format("merge block %d (rmsd %.3f) and %d (rmsd %.3f), total rmsd %.3f\n",
							minb1, blockRmsd[minb1], minb2, blockRmsd[minb2], minrmsd));
				blockSize[minb1] += blockSize[minb2];
				blockRmsd[minb1] = minrmsd;
				for(i = minb2; i < blockNum - 1; i ++)  {
					block2Afp[i] = block2Afp[i + 1];
					blockSize[i] = blockSize[i + 1];
					blockRmsd[i] = blockRmsd[i + 1];
				} //update block information
				afpChainTwiNum --;
				blockNum --;
				for(b1 = 0; b1 < blockNum - 1; b1 ++)   {
					for(b2 = b1 + 1; b2 < blockNum; b2 ++) {
						if(b1 == minb1 || b2 == minb1)  {
							rmsdlist[b1][b2] = combineRmsd(b1, b2, afpChain,ca1,ca2);
						}
						else if(b2 < minb1)     continue;
						else if(b1 < minb1)     {
							rmsdlist[b1][b2] = rmsdlist[b1][b2 + 1];
						}
						else    {
							rmsdlist[b1][b2] = rmsdlist[b1 + 1][b2 + 1];
						}
					}
				} //update the rmsdlist
				merge ++;
			} //merge two blocks
			else if(minrmsd >= 100) break;
			else    {
				rmsdlist[minb1][minb2] += 100;
			} //not merge, modify the rmsdlist so that this combination is not considered in next iteration
		}

		if(merge > 0)       {
			if(debug)
				System.out.println(String.format("Merge %d blocks, remaining %d blocks\n", merge, blockNum));
		}

		if (debug){
			System.err.println("AFPPostProcessor: mergeBlock end blocknum:" + blockNum);
		}
		afpChain.setBlock2Afp(block2Afp);
		afpChain.setBlockSize(blockSize);
		afpChain.setBlockNum(blockNum);
		afpChain.setBlockRmsd(blockRmsd);
		afpChain.setAfpChainTwiNum(afpChainTwiNum);
	}
private static void mergeBlock ( FatCatParameters params , AFPChain afpChain , Atom [ ] ca1 , Atom [ ] ca2 ) { int blockNum = afpChain . getBlockNum ( ) ; double badRmsd = params . getBadRmsd ( ) ; int [ ] block2Afp = afpChain . getBlock2Afp ( ) ; int [ ] blockSize = afpChain . getBlockSize ( ) ; double [ ] blockRmsd = afpChain . getBlockRmsd ( ) ; int afpChainTwiNum = afpChain . getAfpChainTwiNum ( ) ; int i , j , b1 , b2 , minb1 , minb2 ; double minrmsd ; int merge = 0 ; int blockNumOld = blockNum ; double [ ] [ ] rmsdlist = null ; if ( blockNum > 1 ) { rmsdlist = new double [ blockNumOld ] [ blockNumOld ] ; for ( b1 = 0 ; b1 < blockNum - 1 ; b1 ++ ) { for ( b2 = b1 + 1 ; b2 < blockNum ; b2 ++ ) { rmsdlist [ b1 ] [ b2 ] = combineRmsd ( b1 , b2 , afpChain , ca1 , ca2 ) ; } } } minb1 = 0 ; while ( blockNum > 1 ) { minrmsd = 1000 ; for ( i = 0 ; i < blockNum - 1 ; i ++ ) { j = i + 1 ; if ( minrmsd > rmsdlist [ i ] [ j ] ) { minrmsd = rmsdlist [ i ] [ j ] ; minb1 = i ; } } minb2 = minb1 + 1 ; if ( minrmsd < badRmsd ) { if ( debug ) System . out . println ( String . format ( "merge block %d (rmsd %.3f) and %d (rmsd %.3f), total rmsd %.3f\n" , minb1 , blockRmsd [ minb1 ] , minb2 , blockRmsd [ minb2 ] , minrmsd ) ) ; blockSize [ minb1 ] += blockSize [ minb2 ] ; blockRmsd [ minb1 ] = minrmsd ; for ( i = minb2 ; i < blockNum - 1 ; i ++ ) { block2Afp [ i ] = block2Afp [ i + 1 ] ; blockSize [ i ] = blockSize [ i + 1 ] ; blockRmsd [ i ] = blockRmsd [ i + 1 ] ; } afpChainTwiNum -- ; blockNum -- ; for ( b1 = 0 ; b1 < blockNum - 1 ; b1 ++ ) { for ( b2 = b1 + 1 ; b2 < blockNum ; b2 ++ ) { if ( b1 == minb1 || b2 == minb1 ) { rmsdlist [ b1 ] [ b2 ] = combineRmsd ( b1 , b2 , afpChain , ca1 , ca2 ) ; } else if ( b2 < minb1 ) continue ; else if ( b1 < minb1 ) { rmsdlist [ b1 ] [ b2 ] = rmsdlist [ b1 ] [ b2 + 1 ] ; } else { rmsdlist [ b1 ] [ b2 ] = rmsdlist [ b1 + 1 ] [ b2 + 1 ] ; } } } merge ++ ; } else if ( minrmsd >= 100 ) break ; else { rmsdlist [ minb1 ] [ minb2 ] += 100 ; } } if ( merge > 0 ) { if ( debug ) System . out . println ( String . format ( "Merge %d blocks, remaining %d blocks\n" , merge , blockNum ) ) ; } if ( debug ) { System . err . println ( "AFPPostProcessor: mergeBlock end blocknum:" + blockNum ) ; } afpChain . setBlock2Afp ( block2Afp ) ; afpChain . setBlockSize ( blockSize ) ; afpChain . setBlockNum ( blockNum ) ; afpChain . setBlockRmsd ( blockRmsd ) ; afpChain . setAfpChainTwiNum ( afpChainTwiNum ) ; }
Merge consecutive blocks with similar transformation