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

x1192 Stain reagent types #397

Merged
merged 2 commits into from
May 8, 2024
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 @@ -79,6 +79,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 @@ -102,7 +103,7 @@ public GraphQLDataFetchers(ObjectMapper objectMapper, AuthenticationComponent au
LabwareService labwareService, FileStoreService fileStoreService,
SlotRegionService slotRegionService, RecentOpService recentOpService,
FlagLookupService flagLookupService, MeasurementService measurementService,
GraphService graphService) {
GraphService graphService, CommentRepo commentRepo) {
super(objectMapper, authComp, userRepo);
this.sessionConfig = sessionConfig;
this.versionInfo = versionInfo;
Expand Down Expand Up @@ -147,6 +148,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 @@ -474,6 +476,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 @@ -1947,6 +1949,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
Loading
Loading