Skip to content

Commit a877242

Browse files
committed
Disallow MC optimization in parallel
Results do not improve and performance is affected. The interface is maintained so that it can be allowed in the future.
1 parent 72d69a9 commit a877242

File tree

3 files changed

+121
-108
lines changed

3 files changed

+121
-108
lines changed

biojava-structure-gui/src/main/java/demo/DemoMultipleMC.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import org.biojava.nbio.structure.Atom;
1010
import org.biojava.nbio.structure.StructureException;
1111
import org.biojava.nbio.structure.align.StructureAlignment;
12-
import org.biojava.nbio.structure.align.fatcat.FatCatFlexible;
12+
import org.biojava.nbio.structure.align.ce.CeMain;
1313
import org.biojava.nbio.structure.align.gui.MultipleAlignmentDisplay;
1414
import org.biojava.nbio.structure.align.multiple.MultipleAlignment;
1515
import org.biojava.nbio.structure.align.multiple.mc.MultipleMcMain;
@@ -78,8 +78,8 @@ public static void main(String[] args) throws IOException, StructureException, I
7878
}
7979

8080
//Here the multiple structural alignment algorithm comes in place to generate the alignment object
81-
StructureAlignment pairwise = new FatCatFlexible();
82-
//StructureAlignment pairwise = new CeMain();
81+
//StructureAlignment pairwise = new FatCatFlexible();
82+
StructureAlignment pairwise = new CeMain();
8383
MultipleMcMain algorithm = new MultipleMcMain(pairwise);
8484
MultipleMcParameters params = (MultipleMcParameters) algorithm.getParameters();
8585
params.setMinBlockLen(10);

biojava-structure/src/main/java/org/biojava/nbio/structure/align/multiple/mc/MultipleMcMain.java

Lines changed: 105 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.biojava.nbio.structure.align.multiple.MultipleAlignmentEnsemble;
2828
import org.biojava.nbio.structure.align.multiple.MultipleAlignmentEnsembleImpl;
2929
import org.biojava.nbio.structure.align.multiple.MultipleAlignmentImpl;
30-
import org.biojava.nbio.structure.align.multiple.util.MultipleAlignmentScorer;
3130
import org.slf4j.Logger;
3231
import org.slf4j.LoggerFactory;
3332

@@ -52,23 +51,23 @@
5251
*
5352
*/
5453
public 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

Comments
 (0)