|
16 | 16 | import org.labkey.api.pipeline.PipelineService; |
17 | 17 | import org.labkey.api.query.BatchValidationException; |
18 | 18 | import org.labkey.api.security.User; |
| 19 | +import org.labkey.api.targetedms.TargetedMSService; |
19 | 20 | import org.labkey.api.writer.VirtualFile; |
20 | 21 | import org.labkey.panoramapublic.pipeline.CopyExperimentPipelineJob; |
21 | 22 |
|
|
25 | 26 | import java.nio.file.Paths; |
26 | 27 | import java.util.List; |
27 | 28 | import java.util.Objects; |
| 29 | +import java.util.Optional; |
28 | 30 |
|
29 | 31 | /** |
30 | 32 | * This importer does a file move instead of copy to the temp directory and creates a symlink in place of the original |
@@ -90,6 +92,7 @@ public void process(@Nullable PipelineJob job, FolderImportContext ctx, VirtualF |
90 | 92 | PanoramaPublicSymlinkManager.get().moveAndSymLinkDirectory(expJob, ctx.getContainer(), sourceFiles, targetFiles, log); |
91 | 93 |
|
92 | 94 | alignDataFileUrls(expJob.getUser(), ctx.getContainer(), log); |
| 95 | + updateSkydDataIds(expJob.getUser(), ctx.getContainer(), log); |
93 | 96 | } |
94 | 97 | } |
95 | 98 |
|
@@ -154,6 +157,78 @@ private void alignDataFileUrls(User user, Container targetContainer, Logger log) |
154 | 157 | } |
155 | 158 | } |
156 | 159 |
|
| 160 | + /** |
| 161 | + * Fixes incorrect skydDataId reference in TargetedMSRun. This happens when the relative locations of the sky.zip |
| 162 | + * and .skyd file are non-standard in the folder being copied. |
| 163 | + * |
| 164 | + * When a sky.zip file or its exploded folder are moved, post-import, so that the relative locations of sky.zip and |
| 165 | + * its corresponding .skyd file are non-standard, two ExpData rows are created for the skyd file in the Panorama Public |
| 166 | + * copy pipeline job. |
| 167 | + * The first ExpData (linked to the ExpRun) is created during XAR import. |
| 168 | + * The second ExpData (not linked to the ExpRun) is created in the SkylineDocumentParser.parseChromatograms() method. |
| 169 | + * Normally, while running the copy pipeline job, SkylineDocumentParser.parseChromatograms() does not have to create |
| 170 | + * a new ExpData, since an ExpData with the expected path already exists. |
| 171 | + * Having 2 ExpDatas causes: |
| 172 | + * 1. The skydDataId in TargetedMSRun references an ExpData not linked to the ExpRun. It refers to a file in the |
| 173 | + * 'export' directory which gets deleted after folder import. |
| 174 | + * 2. FK violations during cleanup (CopyExperimentFinalTask.cleanupExportDirectory()) prevents deletion of ExpData |
| 175 | + * corresponding to the skydDataId |
| 176 | + * |
| 177 | + * This method finds a match and updates skydDataId in TargetedMSRun in the case where the skyDataId is not linked |
| 178 | + * to the ExpRun. |
| 179 | + */ |
| 180 | + private void updateSkydDataIds(User user, Container targetContainer, Logger log) throws BatchValidationException, ImportException |
| 181 | + { |
| 182 | + log.info("Updating skydDataIds in folder: " + targetContainer.getPath()); |
| 183 | + |
| 184 | + boolean errors = false; |
| 185 | + ExperimentService expService = ExperimentService.get(); |
| 186 | + List<? extends ExpRun> runs = expService.getExpRuns(targetContainer, null, null); |
| 187 | + |
| 188 | + TargetedMSService tmsService = TargetedMSService.get(); |
| 189 | + for (ExpRun run : runs) |
| 190 | + { |
| 191 | + var targetedmsRun = tmsService.getRunByLsid(run.getLSID(), targetContainer); |
| 192 | + if (targetedmsRun == null) continue; |
| 193 | + |
| 194 | + var skydDataId = targetedmsRun.getSkydDataId(); |
| 195 | + if (skydDataId == null) continue; |
| 196 | + |
| 197 | + var skydData = expService.getExpData(skydDataId); |
| 198 | + if (skydData == null) |
| 199 | + { |
| 200 | + log.error("Could not find a row for skydDataId " + skydDataId + " for run " + targetedmsRun.getFileName()); |
| 201 | + errors = true; |
| 202 | + } |
| 203 | + else if (skydData.getRun() == null) |
| 204 | + { |
| 205 | + // skydData is not associated with an ExpRun. Find an ExpData associated with the ExpRun that matches |
| 206 | + // the skydName and update the skydDataId on the run. |
| 207 | + String skydName = skydData.getName(); |
| 208 | + Optional<? extends ExpData> matchingData = run.getAllDataUsedByRun().stream() |
| 209 | + .filter(data -> Objects.equals(skydName, data.getName())) |
| 210 | + .findFirst(); |
| 211 | + |
| 212 | + if (matchingData.isPresent()) |
| 213 | + { |
| 214 | + ExpData data = matchingData.get(); |
| 215 | + log.debug("Updating skydDataId for run " + targetedmsRun.getFileName() + " to " + data.getRowId()); |
| 216 | + tmsService.updateSkydDataId(targetedmsRun, data, user); |
| 217 | + } |
| 218 | + else |
| 219 | + { |
| 220 | + log.error("Could not find matching skyData for run " + targetedmsRun.getFileName()); |
| 221 | + errors = true; |
| 222 | + } |
| 223 | + } |
| 224 | + } |
| 225 | + |
| 226 | + if (errors) |
| 227 | + { |
| 228 | + throw new ImportException("Could not update skydDataIds"); |
| 229 | + } |
| 230 | + } |
| 231 | + |
157 | 232 | public static class Factory extends AbstractFolderImportFactory |
158 | 233 | { |
159 | 234 | @Override |
|
0 commit comments