Skip to content

Commit

Permalink
extract methods for measurement and sample creation in openbis
Browse files Browse the repository at this point in the history
  • Loading branch information
KochTobi committed Jan 7, 2025
1 parent 43ad0d5 commit dc77c3e
Showing 1 changed file with 79 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import life.qbic.application.commons.ApplicationException;
import life.qbic.application.commons.SortOrder;
import life.qbic.logging.api.Logger;
import life.qbic.projectmanagement.application.DataRepoConnectionTester;
Expand All @@ -62,6 +62,7 @@
import life.qbic.projectmanagement.application.dataset.RawDataService.RawDataDatasetInformation;
import life.qbic.projectmanagement.application.sample.SampleIdCodeEntry;
import life.qbic.projectmanagement.domain.model.measurement.MeasurementCode;
import life.qbic.projectmanagement.domain.model.measurement.MeasurementId;
import life.qbic.projectmanagement.domain.model.measurement.NGSMeasurement;
import life.qbic.projectmanagement.domain.model.measurement.ProteomicsMeasurement;
import life.qbic.projectmanagement.domain.model.project.Project;
Expand Down Expand Up @@ -91,6 +92,8 @@ public class OpenbisConnector implements QbicProjectDataRepo, SampleDataReposito
private static final String DEFAULT_EXPERIMENT_TYPE = "Q_SAMPLE_BATCH";
private static final String EXTERNAL_ID_CODE = "Q_EXTERNAL_ID";
private static final String DEFAULT_DELETION_REASON = "Commanded by data manager app";
private static final String NGS_MEASUREMENT_TYPE_CODE = "Q_NGS_MEASUREMENT";
private static final String PROTEOMICS_MEASUREMENT_TYPE_CODE = "Q_PROTEOMICS_MEASUREMENT";
private final OpenbisSessionFactory sessionFactory;
private final IApplicationServerApi applicationServer;
private final IDataStoreServerApi datastoreServer;
Expand Down Expand Up @@ -244,7 +247,7 @@ private String findFreeExperimentCode(String projectCode) {

private int getTrailingNumber(String input) {
int lastNumberInt = 0;
Pattern lastIntPattern = Pattern.compile("[^0-9]+([0-9]+)$");
Pattern lastIntPattern = Pattern.compile("\\D+(\\d+)$");
Matcher matcher = lastIntPattern.matcher(input);
if (matcher.find()) {
String someNumberStr = matcher.group(1);
Expand Down Expand Up @@ -366,90 +369,104 @@ private List<SampleUpdate> convertSamplesToSampleUpdates(
return updatedSamples.stream().map(s -> createSampleUpdate(projectCode, s)).toList();
}

private SampleCreation prepareMeasurementSample(String sampleCode,
String measurementTypeCode, List<SampleIdentifier> parentIds, Map<String, String> metadata) {
SampleCreation sampleCreation = new SampleCreation();
sampleCreation.setCode(sampleCode);
sampleCreation.setParentIds(new ArrayList<>(parentIds));
sampleCreation.setTypeId(new EntityTypePermId(measurementTypeCode));
sampleCreation.setSpaceId(new SpacePermId(DEFAULT_SPACE_CODE));
sampleCreation.setProperties(metadata);
return sampleCreation;
}

@Override
public void addNGSMeasurement(NGSMeasurement measurement, List<SampleCode> parentCodes) {
String TYPE_CODE = "Q_NGS_MEASUREMENT";
Map<String, String> metadata = new HashMap<>();
metadata.put(EXTERNAL_ID_CODE, measurement.measurementId().value());
try (OpenBisSession session = sessionFactory.getSession()) {
List<SampleIdentifier> parentIds = fetchSampleIdentifiers(session,
parentCodes.stream().map(SampleCode::code).toList());
createOpenbisSamples(session, List.of(
prepareMeasurementSample(measurement.measurementCode().value(), TYPE_CODE, parentIds,
metadata)));
}
createMeasurementInOpenbis(parentCodes, NGS_MEASUREMENT_TYPE_CODE, measurement.measurementId(),
measurement.measurementCode());
}

@Override
public void saveAllNGS(
Map<NGSMeasurement, Collection<SampleIdCodeEntry>> ngsMeasurementsMapping) {
String TYPE_CODE = "Q_NGS_MEASUREMENT";
List<SampleCreation> objectsToCreate = new ArrayList<>();

try (OpenBisSession session = sessionFactory.getSession()) {
for (NGSMeasurement measurement : ngsMeasurementsMapping.keySet()) {
List<String> parentCodes = ngsMeasurementsMapping.get(measurement).stream()
.map(entry -> entry.sampleCode().code()).collect(Collectors.toList());
List<SampleIdentifier> parentIds = fetchSampleIdentifiers(session, parentCodes);

Map<String, String> metadata = new HashMap<>();
metadata.put(EXTERNAL_ID_CODE, measurement.measurementId().value());

objectsToCreate.add(prepareMeasurementSample(measurement.measurementCode().value(),
TYPE_CODE, parentIds, metadata));
}
var objectsToCreate = ngsMeasurementsMapping
.entrySet().stream()
.map(
entry -> {
NGSMeasurement measurement = entry.getKey();
Collection<SampleIdCodeEntry> sampleIdCodes = entry.getValue();

List<String> parentCodes = sampleIdCodes.stream()
.map(sampleEntry -> sampleEntry.sampleCode().code())
.toList();
return prepareSampleCreation(NGS_MEASUREMENT_TYPE_CODE, session, parentCodes,
measurement.measurementId(),
measurement.measurementCode());
}
).toList();
createOpenbisSamples(session, objectsToCreate);
}
}

@Override
public void addProteomicsMeasurement(ProteomicsMeasurement measurement,
List<SampleCode> parentCodes) {
String TYPE_CODE = "Q_PROTEOMICS_MEASUREMENT";
createMeasurementInOpenbis(parentCodes, PROTEOMICS_MEASUREMENT_TYPE_CODE,
measurement.measurementId(),
measurement.measurementCode());
}

private void createMeasurementInOpenbis(List<SampleCode> parentCodes, String typeCode,
MeasurementId measurementId, MeasurementCode measurementCode) {
Map<String, String> metadata = new HashMap<>();
metadata.put(EXTERNAL_ID_CODE, measurement.measurementId().value());
metadata.put(EXTERNAL_ID_CODE, measurementId.value());
try (OpenBisSession session = sessionFactory.getSession()) {
List<SampleIdentifier> parentIds = fetchSampleIdentifiers(session,
parentCodes.stream().map(SampleCode::code).toList());
createOpenbisSamples(session, Arrays.asList(
prepareMeasurementSample(measurement.measurementCode().value(), TYPE_CODE, parentIds,
metadata)));
String sampleCode = measurementCode.value();
SampleCreation sampleCreation = new SampleCreation();
sampleCreation.setCode(sampleCode);
sampleCreation.setParentIds(new ArrayList<>(parentIds));
sampleCreation.setTypeId(new EntityTypePermId(typeCode));
sampleCreation.setSpaceId(new SpacePermId(DEFAULT_SPACE_CODE));
sampleCreation.setProperties(metadata);
createOpenbisSamples(session, List.of(
sampleCreation));
}
}

@Override
public void saveAllProteomics(
Map<ProteomicsMeasurement, Collection<SampleIdCodeEntry>> proteomicsMeasurementsMapping) {
String TYPE_CODE = "Q_PROTEOMICS_MEASUREMENT";
List<SampleCreation> objectsToCreate = new ArrayList<>();

try (OpenBisSession session = sessionFactory.getSession()) {
for (ProteomicsMeasurement measurement : proteomicsMeasurementsMapping.keySet()) {
List<String> parentCodes = proteomicsMeasurementsMapping.get(measurement).stream()
.map(entry -> entry.sampleCode().code()).collect(Collectors.toList());
List<SampleIdentifier> parentIds = fetchSampleIdentifiers(session, parentCodes);

Map<String, String> metadata = new HashMap<>();
metadata.put(EXTERNAL_ID_CODE, measurement.measurementId().value());

objectsToCreate.add(prepareMeasurementSample(measurement.measurementCode().value(),
TYPE_CODE, parentIds, metadata));
}
List<SampleCreation> objectsToCreate = proteomicsMeasurementsMapping
.entrySet().stream()
.map(
entry -> {
ProteomicsMeasurement measurement = entry.getKey();
Collection<SampleIdCodeEntry> sampleIdCodes = entry.getValue();

List<String> parentCodes = sampleIdCodes.stream()
.map(sampleEntry -> sampleEntry.sampleCode().code())
.toList();
return prepareSampleCreation(PROTEOMICS_MEASUREMENT_TYPE_CODE, session, parentCodes,
measurement.measurementId(),
measurement.measurementCode());
}
).toList();
createOpenbisSamples(session, objectsToCreate);
}
}

private SampleCreation prepareSampleCreation(String typeCode, OpenBisSession session,
List<String> parentCodes, MeasurementId measurementId, MeasurementCode measurementCode) {
List<SampleIdentifier> parentIds = fetchSampleIdentifiers(session, parentCodes);

Map<String, String> metadata = new HashMap<>();
metadata.put(EXTERNAL_ID_CODE, measurementId.value());

String sampleCode = measurementCode.value();
SampleCreation sampleCreation = new SampleCreation();
sampleCreation.setCode(sampleCode);
sampleCreation.setParentIds(new ArrayList<>(parentIds));
sampleCreation.setTypeId(new EntityTypePermId(typeCode));
sampleCreation.setSpaceId(new SpacePermId(DEFAULT_SPACE_CODE));
sampleCreation.setProperties(metadata);
return sampleCreation;
}

@Override
public void deleteProteomicsMeasurements(List<ProteomicsMeasurement> measurements) {
deleteMeasurements(measurements.stream().map(ProteomicsMeasurement::measurementCode).toList());
Expand All @@ -462,7 +479,7 @@ public void deleteNGSMeasurements(List<NGSMeasurement> measurements) {

private void deleteMeasurements(List<MeasurementCode> measurementCodes) {
try (OpenBisSession session = sessionFactory.getSession()) {
for(MeasurementCode code : measurementCodes) {
for (MeasurementCode code : measurementCodes) {
String sampleCode = code.value();
// measurement has been deleted in JPA at this moment. We don't fail, but we keep data in
// openbis that might have been registered between the check and deletion
Expand Down Expand Up @@ -596,7 +613,6 @@ public List<RawDataDatasetInformation> queryRawDataByMeasurementCodes(String fil
searchCriteria.withAndOperator();
DataSetSearchCriteria filterCriteria = searchCriteria.withSubcriteria().withOrOperator();
filterCriteria.withSample().withCode().thatContains(filter);
//TODO other possibilities to filter by than the measured sample code?
}
try (OpenBisSession session = sessionFactory.getSession()) {

Expand Down Expand Up @@ -674,7 +690,7 @@ private void handleOperations(OpenBisSession session, IOperation operation) {
applicationServer.executeOperations(session.getToken(), operationOptions, executionOptions);
} catch (Exception e) {
log.error("Unexpected exception during openBIS operation.", e);
throw new RuntimeException(e);
throw new ApplicationException("Unexpected exception during openBIS operation.", e);
}
}

Expand All @@ -697,7 +713,9 @@ public boolean projectExists(ProjectCode projectCode) {
public void testDatastoreServer() {
int major = datastoreServer.getMajorVersion();
int minor = datastoreServer.getMinorVersion();
log.info("Successfully tested connection to openBIS datastore server version: %d.%d".formatted(major, minor));
log.info(
"Successfully tested connection to openBIS datastore server version: %d.%d".formatted(major,
minor));
}

@Override
Expand All @@ -713,6 +731,9 @@ public void testApplicationServer() {
// Convenience RTE to describe connection issues
static class ConnectionException extends RuntimeException {

public ConnectionException(String message) {
super(message);
}
}

static class MappingNotFoundException extends RuntimeException {
Expand Down

0 comments on commit dc77c3e

Please sign in to comment.