Skip to content

Commit

Permalink
Merge pull request #397 from sanger/stain_reagent_type
Browse files Browse the repository at this point in the history
x1192 Stain reagent types
  • Loading branch information
khelwood committed May 8, 2024
2 parents 83d12fb + f7e76ec commit b75d9d2
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public class GraphQLDataFetchers extends BaseGraphQLResource {
final FlagLookupService flagLookupService;
final MeasurementService measurementService;
final GraphService graphService;
final CommentRepo commentRepo;

@Autowired
public GraphQLDataFetchers(ObjectMapper objectMapper, AuthenticationComponent authComp, UserRepo userRepo,
Expand All @@ -104,7 +105,7 @@ public GraphQLDataFetchers(ObjectMapper objectMapper, AuthenticationComponent au
SlotRegionService slotRegionService, RecentOpService recentOpService,
CleanedOutSlotService cleanedOutSlotService,
FlagLookupService flagLookupService, MeasurementService measurementService,
GraphService graphService) {
GraphService graphService, CommentRepo commentRepo) {
super(objectMapper, authComp, userRepo);
this.sessionConfig = sessionConfig;
this.versionInfo = versionInfo;
Expand Down Expand Up @@ -150,6 +151,7 @@ public GraphQLDataFetchers(ObjectMapper objectMapper, AuthenticationComponent au
this.flagLookupService = flagLookupService;
this.measurementService = measurementService;
this.graphService = graphService;
this.commentRepo = commentRepo;
}

public DataFetcher<User> getUser() {
Expand Down Expand Up @@ -484,6 +486,10 @@ public DataFetcher<List<StainType>> getEnabledStainTypes() {
return dfe -> stainService.getEnabledStainTypes();
}

public DataFetcher<List<Comment>> getStainReagentTypes() {
return dfe -> commentRepo.findAllByCategoryInAndEnabled(StainType.H_AND_E_MEASUREMENTS, true);
}

public DataFetcher<VisiumPermData> getVisiumPermData() {
return dfe -> visiumPermDataService.load(dfe.getArgument("barcode"));
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/uk/ac/sanger/sccp/stan/GraphQLProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ private RuntimeWiring buildWiring() {
.dataFetcher("worksSummary", graphQLDataFetchers.worksSummary())
.dataFetcher("listFiles", graphQLDataFetchers.listStanFiles())
.dataFetcher("stainTypes", graphQLDataFetchers.getEnabledStainTypes())
.dataFetcher("stainReagentTypes", graphQLDataFetchers.getStainReagentTypes())
.dataFetcher("visiumPermData", graphQLDataFetchers.getVisiumPermData())
.dataFetcher("extractResult", graphQLDataFetchers.getExtractResult())
.dataFetcher("passFails", graphQLDataFetchers.getPassFails())
Expand Down
1 change: 1 addition & 0 deletions src/main/java/uk/ac/sanger/sccp/stan/repo/CommentRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
public interface CommentRepo extends CrudRepository<Comment, Integer> {
List<Comment> findAllByCategory(String category);
List<Comment> findAllByCategoryInAndEnabled(List<String> categories, boolean enabled);
List<Comment> findAllByCategoryAndEnabled(String category, boolean enabled);
Optional<Comment> findByCategoryAndText(String category, String text);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Objects;

import static uk.ac.sanger.sccp.utils.BasicUtils.describe;
import static uk.ac.sanger.sccp.utils.BasicUtils.nullToEmpty;

/**
* A request to perform a stain operation
Expand All @@ -12,15 +13,18 @@
public class StainRequest {
private String stainType;
private List<String> barcodes;
private List<TimeMeasurement> timeMeasurements;
private List<TimeMeasurement> timeMeasurements = List.of();
private String workNumber;
private List<Integer> commentIds = List.of();

public StainRequest() {}

public StainRequest(String stainType, List<String> barcodes, List<TimeMeasurement> timeMeasurements) {
public StainRequest(String stainType, List<String> barcodes, List<TimeMeasurement> timeMeasurements,
List<Integer> commentIds) {
this.stainType = stainType;
this.barcodes = barcodes;
this.timeMeasurements = timeMeasurements;
setTimeMeasurements(timeMeasurements);
setCommentIds(commentIds);
}

public String getStainType() {
Expand All @@ -44,7 +48,7 @@ public List<TimeMeasurement> getTimeMeasurements() {
}

public void setTimeMeasurements(List<TimeMeasurement> timeMeasurements) {
this.timeMeasurements = timeMeasurements;
this.timeMeasurements = nullToEmpty(timeMeasurements);
}

public String getWorkNumber() {
Expand All @@ -55,6 +59,14 @@ public void setWorkNumber(String workNumber) {
this.workNumber = workNumber;
}

public List<Integer> getCommentIds() {
return this.commentIds;
}

public void setCommentIds(List<Integer> commentIds) {
this.commentIds = nullToEmpty(commentIds);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -63,12 +75,14 @@ public boolean equals(Object o) {
return (Objects.equals(this.stainType, that.stainType)
&& Objects.equals(this.barcodes, that.barcodes)
&& Objects.equals(this.timeMeasurements, that.timeMeasurements)
&& Objects.equals(this.workNumber, that.workNumber));
&& Objects.equals(this.workNumber, that.workNumber)
&& Objects.equals(this.commentIds, that.commentIds)
);
}

@Override
public int hashCode() {
return Objects.hash(stainType, barcodes, timeMeasurements, workNumber);
return Objects.hash(stainType, barcodes, timeMeasurements, workNumber, commentIds);
}

@Override
Expand All @@ -78,6 +92,7 @@ public String toString() {
.add("barcodes", barcodes)
.add("timeMeasurements", timeMeasurements)
.add("workNumber", workNumber)
.add("commentIds", commentIds)
.toString();
}
}
33 changes: 30 additions & 3 deletions src/main/java/uk/ac/sanger/sccp/stan/service/StainServiceImp.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
import static uk.ac.sanger.sccp.utils.BasicUtils.nullOrEmpty;
import static uk.ac.sanger.sccp.utils.BasicUtils.repr;

/**
Expand All @@ -26,22 +27,26 @@ public class StainServiceImp implements StainService {
private final LabwareRepo labwareRepo;
private final OperationTypeRepo opTypeRepo;
private final MeasurementRepo measurementRepo;
private final OperationCommentRepo opComRepo;

private final LabwareValidatorFactory labwareValidatorFactory;
private final WorkService workService;
private final OperationService opService;
private final CommentValidationService commentValidationService;

public StainServiceImp(StainTypeRepo stainTypeRepo, LabwareRepo labwareRepo, OperationTypeRepo opTypeRepo,
MeasurementRepo measurementRepo,
MeasurementRepo measurementRepo, OperationCommentRepo opComRepo,
LabwareValidatorFactory labwareValidatorFactory, WorkService workService,
OperationService opService) {
OperationService opService, CommentValidationService commentValidationService) {
this.stainTypeRepo = stainTypeRepo;
this.labwareRepo = labwareRepo;
this.opTypeRepo = opTypeRepo;
this.measurementRepo = measurementRepo;
this.opComRepo = opComRepo;
this.labwareValidatorFactory = labwareValidatorFactory;
this.workService = workService;
this.opService = opService;
this.commentValidationService = commentValidationService;
}

@Override
Expand Down Expand Up @@ -194,20 +199,42 @@ public Iterable<Measurement> recordMeasurements(Collection<Operation> ops, Colle
return measurementRepo.saveAll(measurements);
}

/**
* Records the given comments against every slot/sample in the given operations.
* @param ops the created operations
* @param comments the comments to record
*/
public void recordComments(List<Operation> ops, List<Comment> comments) {
List<OperationComment> opComs = ops.stream()
.flatMap(op -> op.getActions().stream())
.flatMap(ac -> comments.stream()
.map(com -> new OperationComment(null, com, ac.getOperationId(), ac.getSample().getId(), ac.getDestination().getId(), null))
).toList();
opComRepo.saveAll(opComs);
}

@Override
public OperationResult recordStain(User user, StainRequest request) {
Collection<String> problems = new LinkedHashSet<>();
Work work = workService.validateUsableWork(problems, request.getWorkNumber());
Collection<Labware> labware = validateLabware(problems, request.getBarcodes());
StainType stainType = validateStainType(problems, request.getStainType());
List<TimeMeasurement> measurements = validateMeasurements(problems, stainType, request.getTimeMeasurements());

List<Comment> comments;
if (nullOrEmpty(request.getCommentIds())) {
comments = List.of();
} else {
comments = commentValidationService.validateCommentIds(problems, request.getCommentIds().stream());
}
if (!problems.isEmpty()) {
throw new ValidationException("The stain request could not be validated.", problems);
}

List<Operation> ops = createOperations(user, labware, List.of(stainType));
recordMeasurements(ops, measurements);
if (!comments.isEmpty()) {
recordComments(ops, comments);
}
if (work!=null) {
workService.link(work, ops);
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,8 @@ input StainRequest {
timeMeasurements: [TimeMeasurement!]!
"""An optional work number to associate with this operation."""
workNumber: String
"""Comment ids indicating reagent types used in stain."""
commentIds: [Int!]
}

"""The panel used with a stain."""
Expand Down Expand Up @@ -1957,6 +1959,8 @@ type Query {
planData(barcode: String!): PlanData!
"""Get the available stain types."""
stainTypes: [StainType!]!
"""Get the reagent types for H&E staining."""
stainReagentTypes: [Comment!]!
"""Event types."""
eventTypes: [String!]!
"""Get an item of labware and the visium permeabilisation data recorded on it, if any."""
Expand Down

0 comments on commit b75d9d2

Please sign in to comment.