Skip to content

Commit

Permalink
Merge pull request #445 from sanger/metric_run
Browse files Browse the repository at this point in the history
x1224: add run name to SampleMetricsRequest
  • Loading branch information
khelwood authored Sep 6, 2024
2 parents 3167c74 + 3dc04a3 commit e836f1c
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ public class SampleMetricsRequest {
private String operationType;
private String barcode;
private String workNumber;
private String runName;
private List<SampleMetric> metrics = List.of();

// Deserialisation constructor
public SampleMetricsRequest() {}

public SampleMetricsRequest(String operationType, String barcode, String workNumber, List<SampleMetric> metrics) {
public SampleMetricsRequest(String operationType, String barcode, String workNumber, String runName, List<SampleMetric> metrics) {
setOperationType(operationType);
setBarcode(barcode);
setWorkNumber(workNumber);
setRunName(runName);
setMetrics(metrics);
}

Expand Down Expand Up @@ -52,6 +54,15 @@ public void setWorkNumber(String workNumber) {
this.workNumber = workNumber;
}

/** The run name to link to the operation. */
public String getRunName() {
return this.runName;
}

public void setRunName(String runName) {
this.runName = runName;
}

/** The metrics to save. */
public List<SampleMetric> getMetrics() {
return this.metrics;
Expand All @@ -67,6 +78,7 @@ public String toString() {
.add("operationType", operationType)
.add("barcode", barcode)
.add("workNumber", workNumber)
.add("runName", runName)
.add("metrics", metrics)
.reprStringValues()
.toString();
Expand All @@ -80,13 +92,14 @@ public boolean equals(Object o) {
return (Objects.equals(this.operationType, that.operationType)
&& Objects.equals(this.barcode, that.barcode)
&& Objects.equals(this.workNumber, that.workNumber)
&& Objects.equals(this.runName, that.runName)
&& Objects.equals(this.metrics, that.metrics)
);
}

@Override
public int hashCode() {
return Objects.hash(operationType, barcode, workNumber, metrics);
return barcode==null ? 0 : barcode.hashCode();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import uk.ac.sanger.sccp.utils.UCMap;

import javax.persistence.EntityNotFoundException;
import java.util.*;
import java.util.Collection;
import java.util.Set;

/**
* Service helping with {@link uk.ac.sanger.sccp.stan.model.LabwareNote labware notes}
Expand All @@ -27,13 +28,31 @@ public interface LabwareNoteService {
*/
UCMap<Set<String>> findNoteValuesForLabware(Collection<Labware> labware, String name);

/**
* Gets the labware note values for one item of labware with the given note name
* @param lw the labware
* @param name the name of the note
* @return the set of note values
*/
Set<String> findNoteValuesForLabware(Labware lw, String name);

/**
* Records specified notes
* @param name the name of the notes
* @param lwMap map to look up labware by barcode
* @param opMap map to look up operation by labware barcode
* @param values of labware barcode to note value
* @param values map of labware barcode to note value
* @return the created notes
*/
Iterable<LabwareNote> createNotes(String name, UCMap<Labware> lwMap, UCMap<Operation> opMap, UCMap<String> values);

/**
* Records a note
* @param name name of the note
* @param lw the labware
* @param op the operation to link with the note
* @param value note value
* @return the created note
*/
LabwareNote createNote(String name, Labware lw, Operation op, String value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ public LabwareNoteServiceImp(LabwareRepo lwRepo, LabwareNoteRepo lwNoteRepo) {
@Override
public Set<String> findNoteValuesForBarcode(String barcode, String name) throws EntityNotFoundException {
Labware lw = lwRepo.getByBarcode(barcode);
return lwNoteRepo.findAllByLabwareIdInAndName(List.of(lw.getId()), name).stream()
.map(LabwareNote::getValue)
.collect(toLinkedHashSet());
return findNoteValuesForLabware(lw, name);
}

@Override
Expand All @@ -50,6 +48,14 @@ public UCMap<Set<String>> findNoteValuesForLabware(Collection<Labware> labware,
return bcNotes;
}

@Override
public Set<String> findNoteValuesForLabware(Labware lw, String name) {
List<LabwareNote> notes = lwNoteRepo.findAllByLabwareIdInAndName(List.of(lw.getId()), name);
return notes.stream()
.map(LabwareNote::getValue)
.collect(toLinkedHashSet());
}

@Override
public Iterable<LabwareNote> createNotes(String name, UCMap<Labware> lwMap, UCMap<Operation> opMap, UCMap<String> values) {
List<LabwareNote> notes = new ArrayList<>(values.size());
Expand All @@ -68,4 +74,9 @@ public Iterable<LabwareNote> createNotes(String name, UCMap<Labware> lwMap, UCMa
}
return lwNoteRepo.saveAll(notes);
}

@Override
public LabwareNote createNote(String name, Labware lw, Operation op, String value) {
return lwNoteRepo.save(new LabwareNote(null, lw.getId(), op.getId(), name, value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,27 @@
*/
@Service
public class RoiMetricServiceImp implements RoiMetricService {
public static final String RUN_NAME = "run";

private final Clock clock;
private final ValidationHelperFactory valFactory;
private final RoiMetricValidationService valService;
private final OperationService opService;
private final WorkService workService;
private final RoiMetricRepo roiMetricRepo;
private final LabwareNoteService lwNoteService;

@Autowired
public RoiMetricServiceImp(Clock clock, ValidationHelperFactory valFactory,
RoiMetricValidationService valService, OperationService opService,
WorkService workService, RoiMetricRepo roiMetricRepo) {
WorkService workService, LabwareNoteService lwNoteService,
RoiMetricRepo roiMetricRepo) {
this.clock = clock;
this.valFactory = valFactory;
this.valService = valService;
this.opService = opService;
this.workService = workService;
this.lwNoteService = lwNoteService;
this.roiMetricRepo = roiMetricRepo;
}

Expand Down Expand Up @@ -67,16 +72,41 @@ MetricValidation validate(User user, SampleMetricsRequest request) {
val.addProblem("No request supplied.");
return val;
}

UCMap<Labware> lwMap = helper.checkLabware(Collections.singletonList(request.getBarcode()));
if (!lwMap.isEmpty()) {
val.labware = lwMap.values().iterator().next();
val.runName = validateRunName(val.problems, val.labware, request.getRunName());
}
val.work = helper.checkWork(request.getWorkNumber());
val.opType = helper.checkOpType(request.getOperationType(), OperationTypeFlag.IN_PLACE);
val.metrics = valService.validateMetrics(val.problems, val.labware, request.getMetrics());
return val;
}

/**
* Checks for problems with the given run name.
* @param problems receptacle for problems
* @param lw the indicated labware
* @param runName the given run name
* @return sanitised run name
*/
public String validateRunName(Collection<String> problems, Labware lw, String runName) {
if (runName==null) {
return null;
}
runName = runName.trim();
if (runName.isEmpty()) {
return null;
}
Set<String> runNames = lwNoteService.findNoteValuesForLabware(lw, RUN_NAME);
if (!runNames.contains(runName)) {
problems.add(String.format("%s is not a recorded run-name for labware %s.",
runName, lw.getBarcode()));
}
return runName;
}

/**
* Records the given request
* @param user the user responsible for the request
Expand All @@ -88,9 +118,12 @@ OperationResult record(User user, MetricValidation val) {
Operation op = opService.createOperationInPlace(val.opType, user, lw, null, null);

deprecateOldMetrics(clock, lw.getId(), val.metrics);

recordMetrics(lw.getId(), op.getId(), val.metrics);

if (val.runName!=null) {
lwNoteService.createNote(RUN_NAME, lw, op, val.runName);
}

List<Operation> ops = List.of(op);
workService.link(val.work, ops);
return new OperationResult(ops, List.of(lw));
Expand Down Expand Up @@ -128,6 +161,7 @@ static class MetricValidation {
Labware labware;
Work work;
OperationType opType;
String runName;
List<SampleMetric> metrics;

public MetricValidation(Set<String> problems) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,8 @@ input SampleMetricsRequest {
barcode: String!
"""The work number to link to the operation."""
workNumber: String!
"""The run name to link to the operation."""
runName: String
"""The metrics to save."""
metrics: [SampleMetric!]!
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,5 +180,13 @@ private void testSampleMetrics(Labware lw, Work work) throws Exception {
assertEquals("n"+j, rm.getName());
assertEquals("v"+j, rm.getValue());
}

List<LabwareNote> notes = lwNoteRepo.findAllByOperationIdIn(List.of(opId));
assertThat(notes).hasSize(1);
LabwareNote note = notes.getFirst();
assertEquals(lw.getId(), note.getLabwareId());
assertEquals(opId, note.getOperationId());
assertEquals("run", note.getName());
assertEquals("RUN1", note.getValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import static java.util.stream.Collectors.toSet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.Mockito.*;
import static uk.ac.sanger.sccp.stan.Matchers.sameElements;

Expand Down Expand Up @@ -55,6 +56,19 @@ void testFindNoteValuesForBarcode() {
assertThat(service.findNoteValuesForBarcode(bc, name)).containsExactly("val1", "val2");
}

@Test
void testFindNoteValuesForLabware_single() {
Labware lw = EntityFactory.getTube();
String name = "Bananas";
List<LabwareNote> notes = List.of(
new LabwareNote(1, lw.getId(), 11, name, "val1"),
new LabwareNote(2, lw.getId(), 12, name, "val2"),
new LabwareNote(3, lw.getId(), 13, name, "val1")
);
when(mockLwNoteRepo.findAllByLabwareIdInAndName(List.of(lw.getId()), name)).thenReturn(notes);
assertThat(service.findNoteValuesForLabware(lw, name)).containsExactly("val1", "val2");
}

@Test
void testFindNoteValueForLabware_none() {
assertThat(service.findNoteValuesForLabware(List.of(), "Bananas")).isEmpty();
Expand Down Expand Up @@ -115,4 +129,17 @@ void testCreateNotes_none() {
service.createNotes("Bananas", new UCMap<>(), new UCMap<>(), new UCMap<>());
verifyNoInteractions(mockLwNoteRepo);
}

@Test
void testCreateNote() {
String name = "Bananas";
String value = "Alpha";
Labware lw = EntityFactory.getTube();
Operation op = new Operation();
op.setId(10);
LabwareNote createdNote = mock(LabwareNote.class);
when(mockLwNoteRepo.save(any())).thenReturn(createdNote);
assertSame(createdNote, service.createNote(name, lw, op, value));
verify(mockLwNoteRepo).save(new LabwareNote(null, lw.getId(), op.getId(), name, value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ public void testCheckRunNames(boolean valid) {
UCMap<Set<String>> bcValues = new UCMap<>(2);
bcValues.put(lws[0].getBarcode(), Set.of("run1", "runA"));
bcValues.put(lws[1].getBarcode(), Set.of("run2", "runB"));
when(mockLwNoteService.findNoteValuesForLabware(any(), any())).thenReturn(bcValues);
when(mockLwNoteService.findNoteValuesForLabware(anyCollection(), any())).thenReturn(bcValues);

Set<Labware> lwSet;
if (valid) {
Expand Down
Loading

0 comments on commit e836f1c

Please sign in to comment.