Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edit templates for measurement registration #832

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public static Specification<ProteomicsMeasurement> isOrganisationLabel(String fi
public static Specification<ProteomicsMeasurement> isOntologyTermName(String filter) {
return (root, query, builder) -> {
Expression<String> function = builder.function("JSON_EXTRACT", String.class,
root.get("instrument"),
root.get("msDevice"),
builder.literal("$.name"));
return builder.like(function,
"%" + filter + "%");
Expand All @@ -263,7 +263,7 @@ public static Specification<ProteomicsMeasurement> isOntologyTermLabel(String fi
return (root, query, builder) ->
{
Expression<String> function = builder.function("JSON_EXTRACT", String.class,
root.get("instrument"), builder.literal("$.label"));
root.get("msDevice"), builder.literal("$.label"));
return builder.like(function,
"%" + filter + "%");
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,15 +389,20 @@ private Map<ProteomicsMeasurement, Collection<SampleIdCodeEntry>> buildPxP(
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ORGANISATION_ROR_ID);
}

var instrumentQuery = resolveOntologyCURI(firstMetadataEntry.instrumentCURI());
if (instrumentQuery.isEmpty()) {
var msDeviceQuery = resolveOntologyCURI(firstMetadataEntry.msDeviceCURIE());
if (msDeviceQuery.isEmpty()) {
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ONTOLOGY_TERM);
}

var method = new ProteomicsMethodMetadata(instrumentQuery.get(), firstMetadataEntry.facility(),
firstMetadataEntry.digestionMethod(), firstMetadataEntry.digestionEnzyme(),
firstMetadataEntry.enrichmentMethod(), firstMetadataEntry.lcColumn(),
firstMetadataEntry.lcmsMethod(), readInjectionVolume(firstMetadataEntry.injectionVolume()),
var method = new ProteomicsMethodMetadata(msDeviceQuery.get(),
firstMetadataEntry.technicalReplicateName(),
firstMetadataEntry.facility(),
firstMetadataEntry.digestionMethod(),
firstMetadataEntry.digestionEnzyme(),
firstMetadataEntry.enrichmentMethod(),
firstMetadataEntry.lcColumn(),
firstMetadataEntry.lcmsMethod(),
readInjectionVolume(firstMetadataEntry.injectionVolume()),
firstMetadataEntry.labeling()
.labelType());

Expand Down Expand Up @@ -611,12 +616,13 @@ private List<Result<MeasurementId, ErrorCode>> updateAllPxP(
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ORGANISATION_ROR_ID);
}

var instrumentQuery = resolveOntologyCURI(measurementMetadata.instrumentCURI());
if (instrumentQuery.isEmpty()) {
var msDeviceQuery = resolveOntologyCURI(measurementMetadata.msDeviceCURIE());
if (msDeviceQuery.isEmpty()) {
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ONTOLOGY_TERM);
}

var method = new ProteomicsMethodMetadata(instrumentQuery.get(),
var method = new ProteomicsMethodMetadata(msDeviceQuery.get(),
measurementMetadata.technicalReplicateName(),
measurementMetadata.facility(),
measurementMetadata.digestionMethod(), measurementMetadata.digestionEnzyme(),
measurementMetadata.enrichmentMethod(), measurementMetadata.lcColumn(),
Expand All @@ -642,15 +648,20 @@ private List<Result<MeasurementId, ErrorCode>> updateAllPxP(
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ORGANISATION_ROR_ID);
}

var instrumentQuery = resolveOntologyCURI(firstEntry.instrumentCURI());
if (instrumentQuery.isEmpty()) {
var msDeviceQuery = resolveOntologyCURI(firstEntry.msDeviceCURIE());
if (msDeviceQuery.isEmpty()) {
throw new MeasurementRegistrationException(ErrorCode.UNKNOWN_ONTOLOGY_TERM);
}

var method = new ProteomicsMethodMetadata(instrumentQuery.get(), firstEntry.facility(),
firstEntry.digestionMethod(), firstEntry.digestionEnzyme(),
firstEntry.enrichmentMethod(), firstEntry.lcColumn(),
firstEntry.lcmsMethod(), readInjectionVolume(firstEntry.injectionVolume()),
var method = new ProteomicsMethodMetadata(msDeviceQuery.get(),
firstEntry.technicalReplicateName(),
firstEntry.facility(),
firstEntry.digestionMethod(),
firstEntry.digestionEnzyme(),
firstEntry.enrichmentMethod(),
firstEntry.lcColumn(),
firstEntry.lcmsMethod(),
readInjectionVolume(firstEntry.injectionVolume()),
firstEntry.labeling()
.labelType());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,26 @@
*
* @since 1.0.0
*/
public record ProteomicsMeasurementMetadata(String measurementId,
SampleCode sampleCode,
String organisationId, String instrumentCURI,
String samplePoolGroup, String facility,
String fractionName,
String digestionEnzyme,
String digestionMethod, String enrichmentMethod,
String injectionVolume, String lcColumn,
String lcmsMethod, Labeling labeling,
String comment) implements MeasurementMetadata {
public record ProteomicsMeasurementMetadata(
String measurementId,
SampleCode sampleCode,
String technicalReplicateName,
String organisationId,
String msDeviceCURIE,
String samplePoolGroup,
String facility,
String fractionName,
String digestionEnzyme,
String digestionMethod,
String enrichmentMethod,
String injectionVolume,
String lcColumn,
String lcmsMethod,
Labeling labeling,
String comment
) implements MeasurementMetadata {


public static ProteomicsMeasurementMetadata copyWithNewProperties(SampleCode associatedSample,
Labeling labeling,
ProteomicsMeasurementMetadata metadata) {
return new ProteomicsMeasurementMetadata(metadata.measurementId(),
associatedSample,
metadata.organisationId(),
metadata.instrumentCURI(),
metadata.samplePoolGroup(),
metadata.facility(),
metadata.fractionName(),
metadata.digestionEnzyme(),
metadata.digestionMethod(),
metadata.enrichmentMethod(),
metadata.injectionVolume(),
metadata.lcColumn(),
metadata.lcmsMethod(),
labeling,
metadata.comment());
}

@Override
public Optional<String> assignedSamplePoolGroup() {
return Optional.ofNullable(samplePoolGroup.isBlank() ? null : samplePoolGroup);
Expand Down Expand Up @@ -72,4 +60,5 @@ public boolean equals(Object o) {
public int hashCode() {
return measurementId.hashCode();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public ValidationResult validate(ProteomicsMeasurementMetadata measurementMetada
return validationPolicy.validateSampleId(measurementMetadata.sampleCode())
.combine(validationPolicy.validateMandatoryDataProvided(measurementMetadata))
.combine(validationPolicy.validateOrganisation(measurementMetadata.organisationId())
.combine(validationPolicy.validateInstrument(measurementMetadata.instrumentCURI())));
.combine(validationPolicy.validateMsDevice(measurementMetadata.msDeviceCURIE())));
}

/**
Expand All @@ -121,17 +121,18 @@ public ValidationResult validateUpdate(ProteomicsMeasurementMetadata metadata,
.combine(validationPolicy.validateMeasurementCode(metadata.measurementIdentifier().orElse(""))
.combine(validationPolicy.validateMandatoryDataForUpdate(metadata))
.combine(validationPolicy.validateOrganisation(metadata.organisationId())
.combine(validationPolicy.validateInstrument(metadata.instrumentCURI())
.combine(validationPolicy.validateMsDevice(metadata.msDeviceCURIE())
.combine(
validationPolicy.validateDigestionMethod(metadata.digestionMethod())))));
}

public enum PROTEOMICS_PROPERTY {
QBIC_SAMPLE_ID("qbic sample id"),
SAMPLE_LABEL("sample name"),
TECHNICAL_REPLICATE_NAME("technical replicate"),
ORGANISATION_ID("organisation id"),
FACILITY("facility"),
INSTRUMENT("instrument"),
MS_DEVICE("ms device"),
SAMPLE_POOL_GROUP("sample pool group"),
CYCLE_FRACTION_NAME("cycle/fraction name"),
DIGESTION_METHOD("digestion method"),
Expand Down Expand Up @@ -180,6 +181,10 @@ public static boolean isDigestionMethod(String input) {
public String getName() {
return name;
}

public static List<String> getOptions() {
return Arrays.stream(values()).map(DigestionMethod::getName).toList();
}
}

private class ValidationPolicy {
Expand All @@ -188,7 +193,7 @@ private class ValidationPolicy {

private static final String UNKNOWN_ORGANISATION_ID_MESSAGE = "The organisation ID does not seem to be a ROR ID: \"%s\"";

private static final String UNKNOWN_INSTRUMENT_ID = "Unknown instrument id: \"%s\"";
private static final String UNKNOWN_MS_DEVICE_ID = "Unknown ms device id: \"%s\"";

private static final String UNKNOWN_DIGESTION_METHOD = "Unknown digestion method: \"%s\"";

Expand Down Expand Up @@ -242,13 +247,13 @@ ValidationResult validateMeasurementCode(String measurementCode) {
List.of("Measurement Code: Unknown measurement for id '%s'".formatted(measurementCode))));
}

ValidationResult validateInstrument(String instrument) {
var result = terminologyService.findByCurie(instrument);
ValidationResult validateMsDevice(String msDevice) {
var result = terminologyService.findByCurie(msDevice);
if (result.isPresent()) {
return ValidationResult.successful(1);
}
return ValidationResult.withFailures(1,
List.of(UNKNOWN_INSTRUMENT_ID.formatted(instrument)));
List.of(UNKNOWN_MS_DEVICE_ID.formatted(msDevice)));
}

ValidationResult validateDigestionMethod(String digestionMethod) {
Expand All @@ -273,9 +278,9 @@ ValidationResult validateMandatoryDataForUpdate(ProteomicsMeasurementMetadata me
} else {
validation = validation.combine(ValidationResult.successful(1));
}
if (metadata.instrumentCURI().isBlank()) {
if (metadata.msDeviceCURIE().isBlank()) {
validation = validation.combine(
ValidationResult.withFailures(1, List.of("Instrument: missing mandatory metadata")));
ValidationResult.withFailures(1, List.of("MS Device: missing mandatory metadata")));
} else {
validation = validation.combine(ValidationResult.successful(1));
}
Expand Down Expand Up @@ -323,10 +328,10 @@ ValidationResult validateMandatoryDataProvided(
} else {
validation = validation.combine(ValidationResult.successful(1));
}
if (metadata.instrumentCURI().isBlank()) {
if (metadata.msDeviceCURIE().isBlank()) {
validation = validation.combine(
ValidationResult.withFailures(1,
List.of("Instrument: missing mandatory metadata")));
List.of("MS Device: missing mandatory metadata")));
} else {
validation = validation.combine(ValidationResult.successful(1));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import life.qbic.domain.concepts.LocalDomainEventDispatcher;
import java.util.Set;
import life.qbic.domain.concepts.LocalDomainEventDispatcher;
import life.qbic.projectmanagement.domain.Organisation;
import life.qbic.projectmanagement.domain.model.OntologyTerm;
import life.qbic.projectmanagement.domain.model.measurement.event.MeasurementCreatedEvent;
Expand Down Expand Up @@ -93,7 +93,7 @@ private NGSMeasurement(MeasurementId measurementId, ProjectId projectId,
this.measurementId = measurementId;
this.projectId = requireNonNull(projectId, "projectId must not be null");
this.organisation = requireNonNull(organisation, "organisation must not be null");
this.instrument = requireNonNull(method.instrument(), "instrument must not be null");
this.instrument = requireNonNull(method.instrument(), "msDevice must not be null");
this.measurementCode = requireNonNull(measurementCode, "measurement code must not be null");
this.facility = requireNonNull(method.facility(), "facility must not be null");
this.sequencingReadType = requireNonNull(method.sequencingReadType(),
Expand Down Expand Up @@ -136,7 +136,7 @@ public static NGSMeasurement createWithPool(ProjectId projectId, String samplePo
throws IllegalArgumentException {
requireNonNull(measurementCode, "measurement Code must not be null");
requireNonNull(method, "method must not be null");
requireNonNull(method.instrument(), "instrument must not be null");
requireNonNull(method.instrument(), "msDevice must not be null");
if (samplePool.isBlank()) {
throw new IllegalArgumentException("Sample Pool: no value provided");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ public class ProteomicsMeasurement {
private MeasurementId measurementId;

@Column(name = "instrument", columnDefinition = "longtext CHECK (json_valid(`instrument`))")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this change also be reflected in the db?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but this would break all existing measurements. So not sure yet how to go about it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably best to keep as is right now.

private OntologyTerm instrument;
private OntologyTerm msDevice;

@Column(name = "technicalReplicateName")
private String technicalReplicateName;

@Column(name = "samplePool")
private String samplePool = "";
Expand Down Expand Up @@ -127,8 +130,8 @@ private static void evaluateMandatorySpecificMetadata(

private static void evaluateMandatoryMetadata(ProteomicsMethodMetadata method)
throws IllegalArgumentException {
if (method.instrument() == null) {
throw new IllegalArgumentException("Instrument: Missing metadata.");
if (method.msDevice() == null) {
throw new IllegalArgumentException("MS Device: Missing metadata.");
}
if (method.facility().isBlank()) {
throw new IllegalArgumentException("Facility: Missing metadata");
Expand Down Expand Up @@ -157,7 +160,7 @@ public static ProteomicsMeasurement create(ProjectId projectId,
MeasurementCode measurementCode, Organisation organisation, ProteomicsMethodMetadata method,
Collection<ProteomicsSpecificMeasurementMetadata> proteomicsSpecificMeasurementMetadata)
throws IllegalArgumentException {
requireNonNull(method.instrument());
requireNonNull(method.msDevice());
requireNonNull(measurementCode);
requireNonNull(proteomicsSpecificMeasurementMetadata);
if (!measurementCode.isMSDomain()) {
Expand Down Expand Up @@ -215,8 +218,8 @@ public Collection<SampleId> measuredSamples() {
.toList();
}

public OntologyTerm instrument() {
return instrument;
public OntologyTerm msDevice() {
return msDevice;
}

public Organisation organisation() {
Expand Down Expand Up @@ -257,7 +260,8 @@ public void updateMethod(ProteomicsMethodMetadata method) {
}

private void setMethodMetadata(ProteomicsMethodMetadata methodMetadata) {
this.instrument = methodMetadata.instrument();
this.msDevice = methodMetadata.msDevice();
this.technicalReplicateName = methodMetadata.technicalReplicate();
this.facility = methodMetadata.facility();
this.digestionMethod = methodMetadata.digestionMethod();
this.digestionEnzyme = methodMetadata.digestionEnzyme();
Expand Down Expand Up @@ -319,4 +323,8 @@ public int hashCode() {
public Optional<String> comment() {
return Optional.empty();
}

public Optional<String> technicalReplicateName() {
return Optional.ofNullable(technicalReplicateName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@
*
* @since 1.0.0
*/
public record ProteomicsMethodMetadata(OntologyTerm instrument, String facility,
String digestionMethod,
String digestionEnzyme, String enrichmentMethod,
String lcColumn, String lcmsMethod, int injectionVolume,
String labelType) {
public record ProteomicsMethodMetadata(
OntologyTerm msDevice,
String technicalReplicate,
String facility,
String digestionMethod,
String digestionEnzyme,
String enrichmentMethod,
String lcColumn,
String lcmsMethod,
int injectionVolume,
String labelType
) {

}
Loading