|
16 | 16 | package org.labkey.targetedms.view.spectrum; |
17 | 17 |
|
18 | 18 | import org.apache.commons.io.FilenameUtils; |
| 19 | +import org.apache.logging.log4j.Logger; |
19 | 20 | import org.jetbrains.annotations.NotNull; |
20 | 21 | import org.jetbrains.annotations.Nullable; |
21 | 22 | import org.labkey.api.cache.BlockingCache; |
|
24 | 25 | import org.labkey.api.data.Container; |
25 | 26 | import org.labkey.api.security.User; |
26 | 27 | import org.labkey.api.util.FileUtil; |
| 28 | +import org.labkey.api.util.logging.LogHelper; |
27 | 29 | import org.labkey.targetedms.TargetedMSManager; |
28 | 30 | import org.labkey.targetedms.TargetedMSRun; |
29 | 31 | import org.labkey.targetedms.TargetedMSSchema; |
|
42 | 44 | import org.labkey.targetedms.query.PeptideManager; |
43 | 45 | import org.labkey.targetedms.query.PrecursorManager; |
44 | 46 |
|
| 47 | +import java.io.IOException; |
| 48 | +import java.nio.file.Files; |
45 | 49 | import java.nio.file.Path; |
46 | 50 | import java.sql.SQLException; |
47 | 51 | import java.util.ArrayList; |
|
58 | 62 | */ |
59 | 63 | public class LibrarySpectrumMatchGetter |
60 | 64 | { |
| 65 | + private static final Logger LOG = LogHelper.getLogger(LibrarySpectrumMatchGetter.class, "Matches library spectra and retention times for the library spectrum viewer"); |
| 66 | + |
61 | 67 | private static final int CACHE_SIZE = 10; |
62 | 68 |
|
| 69 | + // Reading library spectra and retention times from large spectrum libraries can be slow over network storage. |
| 70 | + // For EncyclopeDIA .elib we read one row per source file for the peptide. This can be hundreds of rows and the needed |
| 71 | + // columns are not in the index, so each table row lookup is a separate network round-trip on GPFS. |
| 72 | + // For BiblioSpec .blib we scan the unindexed RetentionTimes table for the RT of the peptide in all the scans and source |
| 73 | + // files. |
| 74 | + // PanoramaWeb has large files of both types, so the size gate covers both library types. To protect public folders from |
| 75 | + // aggressive bots, library spectra are not shown to guests when the library file is at or above this size. Guests are |
| 76 | + // asked to log in instead. |
| 77 | + private static final long GUEST_SPECTRUM_LIBRARY_SIZE_LIMIT = 500L * 1024 * 1024; // 500 MB |
| 78 | + |
| 79 | + /** |
| 80 | + * Returns true if library spectra should NOT be shown to the given user for the given run, |
| 81 | + * i.e. the user is a guest and the run references a supported spectrum library file that is at |
| 82 | + * or above {@link #GUEST_SPECTRUM_LIBRARY_SIZE_LIMIT}. Logged-in users are never blocked, and |
| 83 | + * small libraries are read in place as before. |
| 84 | + */ |
| 85 | + public static boolean blockSpectraForGuest(User user, long runId) |
| 86 | + { |
| 87 | + if (!user.isGuest()) |
| 88 | + { |
| 89 | + return false; |
| 90 | + } |
| 91 | + for (Path libPath : LibraryManager.getLibraryFilePaths(runId).values()) |
| 92 | + { |
| 93 | + if (isLargeSpectrumLibrary(libPath)) |
| 94 | + { |
| 95 | + return true; |
| 96 | + } |
| 97 | + } |
| 98 | + return false; |
| 99 | + } |
| 100 | + |
| 101 | + private static boolean isLargeSpectrumLibrary(Path libPath) |
| 102 | + { |
| 103 | + // Only .elib/.blib libraries are read for spectra; ignore anything we cannot read. |
| 104 | + if (libPath == null || getReaderForLibrary(FileUtil.getFileName(libPath)) == null) |
| 105 | + { |
| 106 | + return false; |
| 107 | + } |
| 108 | + try |
| 109 | + { |
| 110 | + // Files.size throws NoSuchFileException if the file is missing, so a separate Files.exists |
| 111 | + // check is unnecessary and would add a second filesystem round-trip on network storage. |
| 112 | + return Files.size(libPath) >= GUEST_SPECTRUM_LIBRARY_SIZE_LIMIT; |
| 113 | + } |
| 114 | + catch (IOException e) |
| 115 | + { |
| 116 | + // If we cannot stat the file it is missing or unreadable, in which case the |
| 117 | + // downstream library read will fail too. |
| 118 | + LOG.warn("Could not determine size of spectrum library file " + libPath, e); |
| 119 | + return false; |
| 120 | + } |
| 121 | + } |
| 122 | + |
63 | 123 | private static final BlockingCache<PrecursorKey, List<PeptideIdRtInfo>> _peptideIdRtsCache = |
64 | 124 | CacheManager.getBlockingCache(CACHE_SIZE, CacheManager.DAY, "TargetedMS peptide ID retention times", |
65 | 125 | (precursor, argument) -> { |
|
0 commit comments