1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  package ffx.algorithms.optimize.manybody;
39  
40  import edu.rit.pj.IntegerForLoop;
41  import edu.rit.pj.ParallelRegion;
42  import edu.rit.pj.reduction.SharedDouble;
43  import ffx.algorithms.optimize.RotamerOptimization;
44  import ffx.potential.bonded.Residue;
45  
46  import java.util.ArrayList;
47  import java.util.Arrays;
48  import java.util.logging.Level;
49  import java.util.logging.Logger;
50  import java.util.stream.IntStream;
51  
52  import static java.lang.Double.isFinite;
53  import static java.lang.String.format;
54  
55  public class GoldsteinPairRegion extends ParallelRegion {
56  
57    private static final Logger logger = Logger.getLogger(GoldsteinPairRegion.class.getName());
58  
59    private RotamerOptimization rotamerOptimization;
60    private Residue[] residues;
61    private int i, riA, rjC;
62    private int j, riB, rjD;
63    private int[] possK;
64    private int nK;
65    private final GoldsteinRotamerPairLoop[] goldsteinRotamerPairLoop;
66    private final SharedDouble sharedSumOverK = new SharedDouble();
67    private ArrayList<Residue> blockedResidues;
68  
69    public GoldsteinPairRegion(int nThreads) {
70      goldsteinRotamerPairLoop = new GoldsteinRotamerPairLoop[nThreads];
71    }
72  
73    public void finish() {
74      for (GoldsteinRotamerPairLoop rotamerPairLoop : goldsteinRotamerPairLoop) {
75        blockedResidues.addAll(rotamerPairLoop.blockedResidues);
76      }
77    }
78  
79    public ArrayList<Residue> getMissedResidues() {
80      return blockedResidues;
81    }
82  
83    public double getSumOverK() {
84      return sharedSumOverK.get();
85    }
86  
87    
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100   public void init(Residue[] residues, int i, int riA, int riB, int j, int rjC, int rjD,
101       int[][] bidiResNeighbors, RotamerOptimization rotamerOptimization) {
102     this.residues = residues;
103     this.i = i;
104     this.riA = riA;
105     this.riB = riB;
106     this.j = j;
107     this.rjC = rjC;
108     this.rjD = rjD;
109     this.rotamerOptimization = rotamerOptimization;
110     int[] nI = bidiResNeighbors[i];
111     int[] nJ = bidiResNeighbors[j];
112     IntStream kStream = IntStream.concat(Arrays.stream(nI), Arrays.stream(nJ));
113     possK = kStream.distinct().filter(k -> (k != i && k != j)).sorted().toArray();
114     nK = possK.length;
115   }
116 
117   @Override
118   public void run() {
119     int threadID = getThreadIndex();
120     if (goldsteinRotamerPairLoop[threadID] == null) {
121       goldsteinRotamerPairLoop[threadID] = new GoldsteinRotamerPairLoop();
122     }
123     try {
124       execute(0, nK - 1, goldsteinRotamerPairLoop[threadID]);
125     } catch (Exception e) {
126       logger.log(Level.WARNING, " Exception in GoldsteinPairRegion.", e);
127     }
128   }
129 
130   public void start() {
131     sharedSumOverK.set(0.0);
132     blockedResidues = new ArrayList<>();
133   }
134 
135   private class GoldsteinRotamerPairLoop extends IntegerForLoop {
136 
137     double sumOverK;
138     ArrayList<Residue> blockedResidues;
139 
140     @Override
141     public void finish() {
142       sharedSumOverK.addAndGet(sumOverK);
143     }
144 
145     @Override
146     public void run(int lb, int ub) {
147       if (blockedResidues.isEmpty()) {
148         double locSumOverK = rotamerOptimization.goldsteinPairSumOverK(residues, lb, ub, i, riA, riB,
149             j, rjC, rjD, blockedResidues, possK);
150         
151         if (isFinite(locSumOverK) && blockedResidues.isEmpty()) {
152           sumOverK += locSumOverK;
153         } else {
154           sumOverK = 0;
155         }
156       } else {
157         rotamerOptimization.logIfRank0(
158             format(" Skipping %d to %d because we cannot eliminate", lb, ub), Level.FINE);
159       }
160     }
161 
162     @Override
163     public void start() {
164       sumOverK = 0.0;
165       blockedResidues = new ArrayList<>();
166     }
167   }
168 }