2727import org .biojava .nbio .structure .align .multiple .MultipleAlignmentEnsemble ;
2828import org .biojava .nbio .structure .align .multiple .MultipleAlignmentEnsembleImpl ;
2929import org .biojava .nbio .structure .align .multiple .MultipleAlignmentImpl ;
30- import org .biojava .nbio .structure .align .multiple .util .MultipleAlignmentScorer ;
3130import org .slf4j .Logger ;
3231import org .slf4j .LoggerFactory ;
3332
5251 *
5352 */
5453public class MultipleMcMain implements MultipleStructureAligner {
55-
54+
5655 private static final Logger logger =
5756 LoggerFactory .getLogger (MultipleMcMain .class );
58-
57+
5958 /**
6059 * Version history:<p>
6160 * 1.0 - Initial code implementation from CEMC article.<p>
6261 * 1.1 - Support CP, non-topological and flexible seed alignments.<p>
6362 */
6463 public static final String version = "1.1" ;
6564 public static final String algorithmName = "jMultipleMC" ;
66-
65+
6766 private MultipleMcParameters params ;
6867 private MultipleAlignmentEnsemble ensemble ;
6968 private StructureAlignment pairwise ;
7069 private int reference = 0 ;
71-
70+
7271 /**
7372 * Default constructor.
7473 * Default parameters are used.
@@ -89,7 +88,7 @@ public MultipleMcMain(StructureAlignment pairwiseAlgo){
8988 * the Java API.
9089 * <li>Choose the closest structure to all others as the reference.
9190 * <li>Generate a MultipleAlignment by combining all the alignments to
92- * the reference.
91+ * the reference, that will be used as a seed for the MC optimization .
9392 * </ul>
9493 *
9594 * @param atomArrays List of Atoms to align of the structures
@@ -101,57 +100,57 @@ public MultipleMcMain(StructureAlignment pairwiseAlgo){
101100 private MultipleAlignment generateSeed (List <Atom []> atomArrays )
102101 throws InterruptedException ,
103102 ExecutionException , StructureException {
104-
103+
105104 int size = atomArrays .size ();
106-
105+
107106 //List to store the all-to-all alignments
108107 List <List <AFPChain >> afpAlignments = new ArrayList <List <AFPChain >>();
109108 for (int i =0 ; i <size ; i ++){
110109 afpAlignments .add (new ArrayList <AFPChain >());
111110 for (int j =0 ; j <size ; j ++)
112111 afpAlignments .get (i ).add (null );
113112 }
114-
113+
115114 int threads = params .getNrThreads ();
116115 ExecutorService executor = Executors .newFixedThreadPool (threads );
117- List <Future <AFPChain >> afpFuture = new ArrayList <Future <AFPChain >>();
118-
119- //Create all the possible protein pairwise combinations
120- //(N*(N-1)/2) and call the pairwise alignment algorithm
121- for (int i =0 ; i <size ; i ++){
122- for (int j =i +1 ; j <size ; j ++){
123-
124- Callable <AFPChain > worker = new CallableStructureAlignment (
125- atomArrays .get (i ), atomArrays .get (j ),
126- pairwise .getAlgorithmName (), pairwise .getParameters ());
127-
128- Future <AFPChain > submit = executor .submit (worker );
129- afpFuture .add (submit );
130- }
131- }
132-
133- //Store the resulting AFPChains in the 2D List
134- int index = 0 ; //the alignment index
135- for (int i =0 ; i <size ; i ++){
136- for (int j =i ; j <size ; j ++){
137- if (i !=j ){
138- afpAlignments .get (i ).add (j ,afpFuture .get (index ).get ());
139- afpAlignments .get (j ).add (i ,afpFuture .get (index ).get ());
140- index ++;
141- }
142- }
143- }
144- executor .shutdown ();
145-
146- reference = chooseReferenceRMSD (afpAlignments );
147- boolean flexible = false ;
148- if (pairwise .getAlgorithmName ().contains ("flexible" ))
149- flexible = true ;
150-
151- return combineReferenceAlignments (afpAlignments .get (reference ),
152- atomArrays , reference , flexible );
116+ List <Future <AFPChain >> afpFuture = new ArrayList <Future <AFPChain >>();
117+
118+ //Create all the possible protein pairwise combinations
119+ //(N*(N-1)/2) and call the pairwise alignment algorithm
120+ for (int i =0 ; i <size ; i ++){
121+ for (int j =i +1 ; j <size ; j ++){
122+
123+ Callable <AFPChain > worker = new CallableStructureAlignment (
124+ atomArrays .get (i ), atomArrays .get (j ),
125+ pairwise .getAlgorithmName (), pairwise .getParameters ());
126+
127+ Future <AFPChain > submit = executor .submit (worker );
128+ afpFuture .add (submit );
129+ }
130+ }
131+
132+ //Store the resulting AFPChains in the 2D List
133+ int index = 0 ; //the alignment index
134+ for (int i =0 ; i <size ; i ++){
135+ for (int j =i ; j <size ; j ++){
136+ if (i !=j ){
137+ afpAlignments .get (i ).add (j ,afpFuture .get (index ).get ());
138+ afpAlignments .get (j ).add (i ,afpFuture .get (index ).get ());
139+ index ++;
140+ }
141+ }
142+ }
143+ executor .shutdown ();
144+
145+ reference = chooseReferenceRMSD (afpAlignments );
146+ boolean flexible = false ;
147+ if (pairwise .getAlgorithmName ().contains ("flexible" ))
148+ flexible = true ;
149+
150+ return combineReferenceAlignments (afpAlignments .get (reference ),
151+ atomArrays , reference , flexible );
153152 }
154-
153+
155154 /**
156155 * This method takes the all-to-all pairwise alignments Matrix (as a
157156 * double List of AFPChain) and calculates the structure with the
@@ -162,26 +161,26 @@ private MultipleAlignment generateSeed(List<Atom[]> atomArrays)
162161 * @return int reference index
163162 */
164163 private static int chooseReferenceRMSD (List <List <AFPChain >> afpAlignments ){
165-
164+
166165 int size = afpAlignments .size ();
167-
168- List <Double > RMSDs = new ArrayList <Double >();
169- for (int i =0 ; i <afpAlignments .size (); i ++){
170- double rmsd =0.0 ;
171- for (int j =0 ; j <size ; j ++){
172- if (i !=j )
173- rmsd += afpAlignments .get (i ).get (j ).getTotalRmsdOpt ();
174- }
175- RMSDs .add (rmsd );
176- }
177- int reference = 0 ;
178- for (int i =1 ; i <size ; i ++){
179- if (RMSDs .get (i ) < RMSDs .get (reference )) reference = i ;
180- }
181- logger .info ("Reference structure is " +reference );
182- return reference ;
166+
167+ List <Double > RMSDs = new ArrayList <Double >();
168+ for (int i =0 ; i <afpAlignments .size (); i ++){
169+ double rmsd =0.0 ;
170+ for (int j =0 ; j <size ; j ++){
171+ if (i !=j )
172+ rmsd += afpAlignments .get (i ).get (j ).getTotalRmsdOpt ();
173+ }
174+ RMSDs .add (rmsd );
175+ }
176+ int reference = 0 ;
177+ for (int i =1 ; i <size ; i ++){
178+ if (RMSDs .get (i ) < RMSDs .get (reference )) reference = i ;
179+ }
180+ logger .info ("Reference structure is " +reference );
181+ return reference ;
183182 }
184-
183+
185184 /**
186185 * This method takes a list of pairwise alignments to the reference
187186 * structure and calculates a MultipleAlignment resulting from combining
@@ -202,13 +201,13 @@ private static int chooseReferenceRMSD(List<List<AFPChain>> afpAlignments){
202201 private static MultipleAlignment combineReferenceAlignments (
203202 List <AFPChain > afpList , List <Atom []> atomArrays ,
204203 int ref , boolean flexible ) throws StructureException {
205-
204+
206205 int size = atomArrays .size ();
207206 int length = 0 ; //the number of residues of the reference structure
208207 if (ref ==0 ) length = afpList .get (1 ).getCa1Length ();
209208 else length = afpList .get (0 ).getCa2Length ();
210209 SortedSet <Integer > flexibleBoundaries = new TreeSet <Integer >();
211-
210+
212211 //Stores the equivalencies of all the structures as a double List
213212 List <List <Integer >> equivalencies = new ArrayList <List <Integer >>();
214213 for (int str =0 ; str <size ; str ++){
@@ -218,7 +217,7 @@ private static MultipleAlignment combineReferenceAlignments(
218217 else equivalencies .get (str ).add (null );
219218 }
220219 }
221-
220+
222221 //Now we parse the AFPChains adding the residue equivalencies
223222 for (int str =0 ; str <size ; str ++){
224223 if (str ==ref ) continue ; //avoid self-comparison
@@ -236,34 +235,34 @@ else if (str<ref){
236235 res2 = afpList .get (str ).getOptAln ()[bk ][0 ][i ];
237236 }
238237 equivalencies .get (str ).set (res1 ,res2 );
239-
238+
240239 //Add the flexible boundaries if flexible
241240 if (flexible && i ==0 ) flexibleBoundaries .add (res1 );
242241 }
243242 }
244243 }
245-
244+
246245 //We have translated the equivalencies, we create the MultipleAlignment
247246 MultipleAlignment seed = new MultipleAlignmentImpl ();
248247 seed .getEnsemble ().setAtomArrays (atomArrays );
249248 BlockSet blockSet = new BlockSetImpl (seed );
250249 new BlockImpl (blockSet );
251-
250+
252251 //Store last positions in the block different than null to detect CP
253252 int [] lastResidues = new int [size ];
254253 Arrays .fill (lastResidues , -1 );
255-
254+
256255 //We loop through all the equivalencies checking for CP
257256 for (int pos =0 ; pos <length ; pos ++){
258257 //Start a new BlockSet if the position means a boundary
259258 if (flexibleBoundaries .contains (pos ) &&
260259 blockSet .getBlocks ().get (blockSet .getBlocks ().size ()-1 ).
261260 getAlignRes () != null ){
262-
261+
263262 blockSet = new BlockSetImpl (seed );
264263 new BlockImpl (blockSet );
265264 }
266-
265+
267266 boolean cp = false ;
268267 for (int str =0 ; str <size ; str ++){
269268 if (equivalencies .get (str ).get (pos ) == null ){
@@ -277,17 +276,17 @@ else if (str<ref){
277276 new BlockImpl (blockSet );
278277 Arrays .fill (lastResidues ,-1 );
279278 }
280-
279+
281280 //Now add the equivalent residues into the Block AlignRes variable
282281 for (int str =0 ; str <size ; str ++){
283282 Block lastB = blockSet .getBlocks ().get (
284283 blockSet .getBlocks ().size ()-1 );
285-
284+
286285 if (lastB .getAlignRes () == null ){
287286 //Initialize the aligned residues list
288287 List <List <Integer >> alnRes =
289288 new ArrayList <List <Integer >>(size );
290-
289+
291290 for (int k =0 ; k <size ; k ++) {
292291 alnRes .add (new ArrayList <Integer >());
293292 }
@@ -304,33 +303,39 @@ else if (str<ref){
304303 @ Override
305304 public MultipleAlignment align (List <Atom []> atomArrays , Object parameters )
306305 throws StructureException {
307-
306+
308307 MultipleAlignment result = null ;
309308 ensemble = new MultipleAlignmentEnsembleImpl ();
310309 ensemble .setAtomArrays (atomArrays );
311310 ensemble .setAlgorithmName (algorithmName );
312311 ensemble .setVersion (version );
313312 ensemble .setIoTime (System .currentTimeMillis ());
314313 setParameters ((ConfigStrucAligParams ) parameters );
315-
316- //Generate the seed alignment from all-to-all pairwise alignments
314+
315+ //Generate the seed alignment and optimize it
317316 try {
318317 result = generateSeed (atomArrays );
319- int threads = params .getNrThreads ();
318+ } catch (InterruptedException e ) {
319+ logger .warn ("Seed generation failed." ,e );
320+ } catch (ExecutionException e ) {
321+ logger .warn ("Seed generation failed." ,e );
322+ }
323+
324+ //Repeat the optimization in parallel - DISALLOWED
325+ /*int threads = params.getNrThreads();
320326 ExecutorService executor = Executors.newFixedThreadPool(threads);
321327 List<Future<MultipleAlignment>> msaFuture =
322328 new ArrayList<Future<MultipleAlignment>>();
323-
324- //Repeat the optimization in parallel
329+
325330 for (int i=0; i<params.getNrThreads(); i++){
326331 //Change the random seed for each parallelization
327332 MultipleMcParameters paramsMC = (MultipleMcParameters) params;
328333 paramsMC.setRandomSeed(paramsMC.getRandomSeed()+i);
329-
334+
330335 Callable<MultipleAlignment> worker =
331336 new MultipleMcOptimizer(
332337 result, paramsMC, reference);
333-
338+
334339 Future<MultipleAlignment> submit = executor.submit(worker);
335340 msaFuture.add(submit);
336341 }
@@ -347,25 +352,29 @@ public MultipleAlignment align(List<Atom[]> atomArrays, Object parameters)
347352 }
348353 Long runtime = System.currentTimeMillis()-ensemble.getIoTime();
349354 ensemble.setCalculationTime(runtime);
350-
355+
351356 result.setEnsemble(ensemble);
352357 ensemble.addMultipleAlignment(result);
353- executor .shutdown ();
354- return result ;
355-
356- } catch (InterruptedException e ) {
357- logger .warn ("Optimization run failed: " +e .getMessage ());
358- } catch (ExecutionException e ) {
359- logger .warn ("Optimization run failed: " +e .getMessage ());
360- }
361-
358+ executor.shutdown();*/
359+
360+ MultipleMcOptimizer optimizer = new MultipleMcOptimizer (
361+ result , params , reference );
362+
363+ Long runtime = System .currentTimeMillis ()-ensemble .getIoTime ();
364+ ensemble .setCalculationTime (runtime );
365+
366+ result = optimizer .optimize ();
367+ result .setEnsemble (ensemble );
368+ ensemble .addMultipleAlignment (result );
369+
362370 return result ;
371+
363372 }
364-
373+
365374 @ Override
366375 public MultipleAlignment align (List <Atom []> atomArrays )
367376 throws StructureException {
368-
377+
369378 if (params == null ) {
370379 logger .info ("Using DEFAULT MultipleMc Parameters" );
371380 params = new MultipleMcParameters ();
0 commit comments