$darkmode
DENOPTIM
RingClosuresArchive.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.graph.rings;
20
21import java.io.BufferedReader;
22import java.io.File;
23import java.io.FileInputStream;
24import java.io.FileOutputStream;
25import java.io.FileReader;
26import java.io.IOException;
27import java.io.ObjectInputStream;
28import java.io.ObjectOutputStream;
29import java.io.RandomAccessFile;
30import java.nio.channels.FileChannel;
31import java.nio.channels.FileLock;
32import java.nio.channels.OverlappingFileLockException;
33import java.util.ArrayList;
34import java.util.HashMap;
35import java.util.logging.Level;
36
37import denoptim.exception.DENOPTIMException;
38import denoptim.files.FileUtils;
39
40
49{
53 private int nextRccId = 0;
54
63 private HashMap<String,ArrayList<String>> rccsPerChainId =
64 new HashMap<>();
65
75 private HashMap<Integer,ArrayList<ClosableChain>> libCCxTPIdx =
76 new HashMap<>();
77
82
83 //----------------------------------------------------------------------------
84
89
90//----------------------------------------------------------------------------
91
99 {
101 {
103 }
104 }
105
106//----------------------------------------------------------------------------
107
108 private void readLibraryOfRCCs(String filename) throws DENOPTIMException
109 {
110 BufferedReader br = null;
111 String line = null;
112 try
113 {
114 br = new BufferedReader(new FileReader(filename));
115 while ((line = br.readLine()) != null)
116 {
117 if (line.trim().length() == 0)
118 {
119 continue;
120 }
121
122 String[] parts = line.trim().split("\\s+");
123 String chainIdStr = parts[0];
124 String rccIdNum = parts[1];
125 String closability = parts[2];
126
127 if (Integer.parseInt(rccIdNum) != nextRccId)
128 {
129 String msg = "Expecting RCC Ids to be ordered (i.e., "
130 + "1,2,3,...,n), but inconsistent number "
131 + "is found in " + filename + " - Found"
132 + rccIdNum + " instead of " + nextRccId;
133 throw new DENOPTIMException(msg);
134 }
135
136 if (rccsPerChainId.containsKey(chainIdStr))
137 {
138 String msg = "Found duplicate in library of RCCs";
139 throw new DENOPTIMException(msg);
140 }
141
142 addRecord(chainIdStr,rccIdNum,closability);
143 }
144 }
145 catch (NumberFormatException | IOException nfe)
146 {
147 throw new DENOPTIMException(nfe);
148 }
149 finally
150 {
151 try
152 {
153 if (br != null)
154 {
155 br.close();
156 }
157 }
158 catch (IOException ioe)
159 {
160 throw new DENOPTIMException(ioe);
161 }
162 }
163
164 if (rccsPerChainId.isEmpty())
165 {
166 String err = "No entry taken from RCC index file: ";
167 throw new DENOPTIMException(err + " " + filename);
168 }
169 }
170
171//----------------------------------------------------------------------------
172
173 private void addRecord(String chainId, String rccIdNum,
174 String closability) throws DENOPTIMException
175 {
176 // Create record for RCC
177 ArrayList<String> record = new ArrayList<String>();
178 record.add(rccIdNum);
179 record.add(closability);
180
181 // Store (closability,rccIndex)-x-chainID
182 rccsPerChainId.put(chainId,record);
183
184 // Store (closable chain)-x-vertexMolId
185 if (closability.equals("T"))
186 {
187//TODO per each fragment with more than 3 APs store the link to a ClosableChain
188// not a new one. Might need to store the number of APs as a property of
189// the ChainLinks, that is, change to format of the chainId string to include also that info
190 ClosableChain cc = new ClosableChain(chainId);
191 int tpId = cc.getTurningPointIdx();
192 if (libCCxTPIdx.containsKey(tpId))
193 {
194 libCCxTPIdx.get(tpId).add(cc);
195 }
196 else
197 {
198 ArrayList<ClosableChain> lstCC = new ArrayList<ClosableChain>();
199 lstCC.add(cc);
200 libCCxTPIdx.put(tpId,lstCC);
201 }
202 }
203
204 // Increment counter
205 nextRccId++;
206 }
207
208//----------------------------------------------------------------------------
209
218 public void storeEntry(String chainId, boolean closable,
220 {
221 String closability = "F";
222 if (closable)
223 {
224 closability = "T";
225 }
226
227 File file = new File(settings.getRCCLibraryIndexFile());
228 long fileLength = file.length();
229 RandomAccessFile rafile = null;
230 FileChannel channel = null;
231 FileLock lock = null;
232 try
233 {
234 // Lock the index file
235 rafile = new RandomAccessFile(file, "rw");
236 channel = rafile.getChannel();
237
238 int nTry = 0;
239 while (true)
240 {
241 try
242 {
243 lock = channel.tryLock();
244 if (lock != null)
245 break;
246 }
247 catch (OverlappingFileLockException e)
248 {
249 nTry++;
250 settings.getLogger().log(Level.WARNING,"Attempt " + nTry
251 + " to get lock " + "for '"
253 + "' failed. ");
254 }
255 }
256
257 if (rccsPerChainId.containsKey(chainId))
258 {
259 throw new DENOPTIMException("Found duplicate in library of "
260 + " RingClosingConformations");
261 }
262
263 // Add record in maps (objects kept in memory)
264 String rccId = Integer.toString(nextRccId);
265 addRecord(chainId,rccId,closability);
266
267 // Update RCC index file
268 if (closable)
269 {
270 rafile.seek(fileLength);
271 rafile.writeBytes(chainId + " " + rccId + " " + "T" +"\n");
272 channel.force(true);
274 {
275 String rccFileName = settings.getRCCLibraryFolder()
276 + "/" + rccId + ".ser";
277 FileOutputStream fos = null;
278 ObjectOutputStream oos = null;
279 try
280 {
281 fos = new FileOutputStream(rccFileName);
282 oos = new ObjectOutputStream(fos);
283 oos.writeObject(rcc);
284 oos.close();
285 settings.getLogger().log(Level.FINE,
286 "Serialization to file " + rccFileName);
287 }
288 catch (Throwable t2)
289 {
290 throw new DENOPTIMException(t2);
291 }
292 finally
293 {
294 fos.flush();
295 fos.close();
296 fos = null;
297 }
298 }
299 }
300 else
301 {
302 rafile.seek(fileLength);
303 rafile.writeBytes(chainId + " " + rccId + " " + "F" +"\n");
304 channel.force(true);
305 }
306 }
307 catch (Throwable t)
308 {
309 throw new IllegalStateException("Exception while trying to store "
310 + chainId,t);
311 }
312 finally
313 {
314 try
315 {
316 if (channel != null)
317 channel.close();
318 if (rafile != null)
319 rafile.close();
320 if (lock != null && lock.isValid())
321 lock.release();
322 }
323 catch (Throwable t)
324 {
325 throw new IllegalStateException("RingClosuresArchive is unable "
326 + "to unlock file '"
328 + "'. " + t);
329 }
330 }
331 }
332
333//-----------------------------------------------------------------------------
334
342 public ArrayList<ClosableChain> getCCFromTurningPointId(int tpId)
343 {
344 if (libCCxTPIdx.containsKey(tpId))
345 {
346 return libCCxTPIdx.get(tpId);
347 }
348 return new ArrayList<ClosableChain>();
349 }
350
351//----------------------------------------------------------------------------
352
360 public String containsChain(PathSubGraph chain)
361 {
362 String result = "";
363 for (String altChId : chain.getAllAlternativeChainIDs())
364 {
365 if (rccsPerChainId.containsKey(altChId))
366 {
367 result = altChId;
368 break;
369 }
370 }
371 return result;
372 }
373
374//----------------------------------------------------------------------------
375
380 public boolean getClosabilityOfChain(String chainId)
381 {
382 ArrayList<String> rccRecord = rccsPerChainId.get(chainId);
383 String closability = rccRecord.get(1);
384 return closability.equals("T");
385 }
386
387//----------------------------------------------------------------------------
388
395 {
396 ArrayList<String> rccRecord = rccsPerChainId.get(chainId);
397 int rccId = Integer.parseInt(rccRecord.get(0));
398 String closability = rccRecord.get(1);
399
401 if (closability.equals("T"))
402 {
403 rcc = getRCCsFromArchive(rccId);
404 if (settings.getVerbosity() > 1)
405 {
406 settings.getLogger().log(Level.FINE,
407 "Path is closable (from DB)");
408 }
409 }
410 else
411 {
412 if (settings.getVerbosity() > 1)
413 {
414 settings.getLogger().log(Level.FINE,
415 "Path is NOT closable (from DB)");
416 }
417 }
418 return rcc;
419 }
420
421//----------------------------------------------------------------------------
422
430 {
432
433 String rccFileName1 = settings.getRCCLibraryFolder() +
434 System.getProperty("file.separator") + rccId + ".ser";
435 FileInputStream fis = null;
436 ObjectInputStream ois = null;
437 boolean recoveringDone = false;
438 try
439 {
440 fis = new FileInputStream(rccFileName1);
441 ois = new ObjectInputStream(fis);
442 rcc = (RingClosingConformations) ois.readObject();
443 ois.close();
444 settings.getLogger().log(Level.FINE,
445 "Got serialized RCC from " + rccFileName1);
446 recoveringDone = true;
447 }
448 catch (Throwable t2)
449 {
450 throw new IllegalStateException(t2);
451 }
452 finally
453 {
454 try
455 {
456 fis.close();
457 }
458 catch (Throwable t)
459 {
460 throw new IllegalStateException(t);
461 }
462 }
463 if (!recoveringDone)
464 {
465 String s = "Failed attempt to recover RCC. Check code.";
466 throw new IllegalStateException(s);
467 }
468 return rcc;
469 }
470
471//----------------------------------------------------------------------------
472}
static boolean checkExists(String fileName)
Definition: FileUtils.java:241
ClosableChain represents a chain of fragments (chain links) that is closable (or candidate closable).
int getTurningPointIdx()
Get the vertex ID of the turning point.Note that since the chain is a path in a graph the relative di...
This object represents a path in a DGraph.
List< String > getAllAlternativeChainIDs()
Returns all the possible IDs for this chain.
Serializable object to store/get a list of conformations that allow to close a ring from an open chai...
Parameters and setting related to handling ring closures.
int getVerbosity()
Returns the level of verbosity, i.e., the amount of log that we want to print.
boolean serializeRCCs
FLag controlling the serialization of the RingClosingConformations.
Data structure to store and handle information about sub-structures (i.e., chains of fragments) and r...
void addRecord(String chainId, String rccIdNum, String closability)
RingClosingConformations getRCCsOfChain(String chainId)
void storeEntry(String chainId, boolean closable, RingClosingConformations rcc)
Append a new closable chain entry to the archive.
HashMap< Integer, ArrayList< ClosableChain > > libCCxTPIdx
Data structure containing the library of ClosableChains per each fragment that can act as a turning p...
int nextRccId
Index of the next entry to be added to the archive.
RingClosuresArchive()
Construct an empty archive.
RingClosingConformations getRCCsFromArchive(int rccId)
Get serialized RingClosingConformations from archive.
RingClosuresArchive(RingClosureParameters settings)
Construct the library of ring closing substructures from an existing index file.
ArrayList< ClosableChain > getCCFromTurningPointId(int tpId)
Returns the library of closable chains having the given turning point (i.e., the fragments involved i...
RingClosureParameters settings
Parameters.
HashMap< String, ArrayList< String > > rccsPerChainId
Data structure containing the main information about the RingClosingConformations (values) per each C...
Logger getLogger()
Get the name of the program specific logger.