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

AbDisc: Plate Templates (Part 1) #5467

Merged
merged 16 commits into from
May 2, 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
17 changes: 5 additions & 12 deletions api/src/org/labkey/api/assay/AbstractAssayProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.labkey.api.assay.actions.UploadWizardAction;
import org.labkey.api.assay.pipeline.AssayRunAsyncContext;
import org.labkey.api.assay.plate.AssayPlateMetadataService;
import org.labkey.api.assay.plate.PlateMetadataDataHandler;
import org.labkey.api.assay.security.DesignAssayPermission;
import org.labkey.api.audit.AuditLogService;
import org.labkey.api.data.ActionButton;
Expand Down Expand Up @@ -143,10 +142,6 @@
import static org.labkey.api.data.CompareType.IN;
import static org.labkey.api.util.PageFlowUtil.jsString;

/**
* User: jeckels
* Date: Sep 14, 2007
*/
public abstract class AbstractAssayProvider implements AssayProvider
{
public static final String ASSAY_NAME_SUBSTITUTION = "${AssayName}";
Expand Down Expand Up @@ -911,15 +906,13 @@ public List<Pair<Domain, Map<DomainProperty, Object>>> getDomains(ExpProtocol pr
sortDomainList(domains);

// see if there is a plate metadata domain associated with this protocol
if (AssayPlateMetadataService.getService(PlateMetadataDataHandler.DATA_TYPE) != null)
Domain plateDomain = AssayPlateMetadataService.get().getPlateDataDomain(protocol);
if (plateDomain != null)
{
Domain plateDomain = AssayPlateMetadataService.getService(PlateMetadataDataHandler.DATA_TYPE).getPlateDataDomain(protocol);
if (plateDomain != null)
{
Map<DomainProperty, Object> values = DefaultValueService.get().getDefaultValues(plateDomain.getContainer(), plateDomain);
domains.add(new Pair<>(plateDomain, values));
}
Map<DomainProperty, Object> values = DefaultValueService.get().getDefaultValues(plateDomain.getContainer(), plateDomain);
domains.add(new Pair<>(plateDomain, values));
}

return domains;
}

Expand Down
123 changes: 52 additions & 71 deletions api/src/org/labkey/api/assay/AbstractAssayTsvDataHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@
import static java.util.stream.Collectors.toList;
import static org.labkey.api.gwt.client.ui.PropertyType.SAMPLE_CONCEPT_URI;

/**
* User: jeckels
* Date: Jan 3, 2008
*/
public abstract class AbstractAssayTsvDataHandler extends AbstractExperimentDataHandler implements ValidationDataHandler
{
protected static final Object ERROR_VALUE = new Object() {
Expand Down Expand Up @@ -210,18 +206,14 @@ public Map<DataType, List<Map<String, Object>>> getValidationDataMap(ExpData dat
List<Map<String, Object>> dataRows = loader.load();
boolean skipFirstRowAdjustment = dataRows.isEmpty();

if (plateMetadataEnabled)
if (plateMetadataEnabled && AssayPlateMetadataService.isExperimentalAppPlateEnabled())
{
AssayPlateMetadataService svc = AssayPlateMetadataService.getService(PlateMetadataDataHandler.DATA_TYPE);
if (AssayPlateMetadataService.isExperimentalAppPlateEnabled() && svc != null)
{
Pair<String, Boolean> plateIdAdded = new Pair<>("PlateIdAdded", false);
Integer plateSetId = getPlateSetValueFromRunProps(context, provider, protocol);
dataRows = svc.parsePlateData(context.getContainer(), context.getUser(), provider, protocol, plateSetId, dataFile, dataRows, plateIdAdded);
Pair<String, Boolean> plateIdAdded = new Pair<>("PlateIdAdded", false);
Integer plateSetId = getPlateSetValueFromRunProps(context, provider, protocol);
dataRows = AssayPlateMetadataService.get().parsePlateData(context.getContainer(), context.getUser(), provider, protocol, plateSetId, dataFile, dataRows, plateIdAdded);

// need to do this otherwise the added plateID may get stripped
skipFirstRowAdjustment = plateIdAdded.second;
}
// need to do this otherwise the added plateID may get stripped
skipFirstRowAdjustment = plateIdAdded.second;
}

// loader did not parse any rows
Expand Down Expand Up @@ -249,29 +241,27 @@ private List<Map<String, Object>> mergePlateMetadata(XarContext context, AssayPr
Map<String, AssayPlateMetadataService.MetadataLayer> rawPlateMetadata, File plateMetadataFile)
throws ExperimentException
{
AssayPlateMetadataService svc = AssayPlateMetadataService.getService(PlateMetadataDataHandler.DATA_TYPE);
if (svc != null)
Map<String, AssayPlateMetadataService.MetadataLayer> plateMetadata = null;
if (plateMetadataFile != null || rawPlateMetadata != null)
{
Map<String, AssayPlateMetadataService.MetadataLayer> plateMetadata = null;
if (plateMetadataFile != null || rawPlateMetadata != null)
{
plateMetadata = plateMetadataFile != null
? svc.parsePlateMetadata(plateMetadataFile)
: rawPlateMetadata;
}
if (plateMetadataFile != null)
plateMetadata = AssayPlateMetadataService.get().parsePlateMetadata(plateMetadataFile);
else
plateMetadata = rawPlateMetadata;
}

Domain runDomain = provider.getRunDomain(protocol);
DomainProperty propertyPlateTemplate = runDomain.getPropertyByName(AssayPlateMetadataService.PLATE_TEMPLATE_COLUMN_NAME);
DomainProperty propertyPlateSet = runDomain.getPropertyByName(AssayPlateMetadataService.PLATE_SET_COLUMN_NAME);
if (propertyPlateTemplate != null || propertyPlateSet != null)
{
Map<DomainProperty, String> runProps = ((AssayUploadXarContext)context).getContext().getRunProperties();
Object lsid = runProps.getOrDefault(propertyPlateTemplate, null);
Lsid templateLsid = lsid != null && !StringUtils.isEmpty(String.valueOf(lsid)) ? Lsid.parse(String.valueOf(lsid)) : null;
Integer plateSetId = getPlateSetValueFromRunProps(context, provider, protocol);
return svc.mergePlateMetadata(context.getContainer(), context.getUser(), templateLsid, plateSetId, dataRows, plateMetadata, provider, protocol);
}
Domain runDomain = provider.getRunDomain(protocol);
DomainProperty propertyPlateTemplate = runDomain.getPropertyByName(AssayPlateMetadataService.PLATE_TEMPLATE_COLUMN_NAME);
DomainProperty propertyPlateSet = runDomain.getPropertyByName(AssayPlateMetadataService.PLATE_SET_COLUMN_NAME);
if (propertyPlateTemplate != null || propertyPlateSet != null)
{
Map<DomainProperty, String> runProps = ((AssayUploadXarContext)context).getContext().getRunProperties();
Object lsid = runProps.getOrDefault(propertyPlateTemplate, null);
Lsid templateLsid = lsid != null && !StringUtils.isEmpty(String.valueOf(lsid)) ? Lsid.parse(String.valueOf(lsid)) : null;
Integer plateSetId = getPlateSetValueFromRunProps(context, provider, protocol);
return AssayPlateMetadataService.get().mergePlateMetadata(context.getContainer(), context.getUser(), templateLsid, plateSetId, dataRows, plateMetadata, provider, protocol);
}

return dataRows;
}

Expand All @@ -293,8 +283,6 @@ private Integer getPlateSetValueFromRunProps(XarContext context, AssayProvider p
/**
* Creates a DataLoader that can handle missing value indicators if the columns on the domain
* are configured to support it.
*
* @throws ExperimentException
*/
public static DataLoader createLoaderForImport(File dataFile, @Nullable Domain dataDomain, DataLoaderSettings settings, boolean shouldInferTypes) throws ExperimentException
{
Expand All @@ -310,7 +298,7 @@ public static DataLoader createLoaderForImport(File dataFile, @Nullable Domain d
{
if (col.isMvEnabled())
{
// Check for all of the possible names for the column in the incoming data when deciding if we should
// Check for all possible names for the column in the incoming data when deciding if we should
// check it for missing values
Set<String> columnAliases = ImportAliasable.Helper.createImportMap(Collections.singletonList(col), false).keySet();
mvEnabledColumns.addAll(columnAliases);
Expand Down Expand Up @@ -689,22 +677,16 @@ private void addAssayPlateMetadata(
if (datas.size() == 1)
{
ExpData plateData = datas.get(0);
AssayPlateMetadataService svc = AssayPlateMetadataService.getService((AssayDataType)plateData.getDataType());
if (svc != null)
{
Map<String, AssayPlateMetadataService.MetadataLayer> plateMetadata;

if (plateData.getFile() != null)
plateMetadata = svc.parsePlateMetadata(plateData.getFile());
else if (getRawPlateMetadata() != null)
plateMetadata = getRawPlateMetadata();
else
throw new ExperimentException("There was no plate metadata JSON available for this run");
Map<String, AssayPlateMetadataService.MetadataLayer> plateMetadata;

svc.addAssayPlateMetadata(resultData, plateMetadata, container, user, run, provider, protocol, inserted, rowIdToLsidMap);
}
if (plateData.getFile() != null)
plateMetadata = AssayPlateMetadataService.get().parsePlateMetadata(plateData.getFile());
else if (getRawPlateMetadata() != null)
plateMetadata = getRawPlateMetadata();
else
throw new ExperimentException("No PlateMetadataService registered for data type : " + plateData.getDataType().toString());
throw new ExperimentException("There was no plate metadata JSON available for this run");

AssayPlateMetadataService.get().addAssayPlateMetadata(resultData, plateMetadata, container, user, run, provider, protocol, inserted, rowIdToLsidMap);
}
else
{
Expand All @@ -720,32 +702,31 @@ protected ParticipantVisitResolver createResolver(User user, ExpRun run, ExpProt
return AssayService.get().createResolver(user, run, protocol, provider, null);
}

/** Insert the data into the database. Transaction is active. */
protected List<Map<String, Object>> insertRowData(ExpData data, User user, Container container, ExpRun run, ExpProtocol protocol, AssayProvider provider,Domain dataDomain, List<Map<String, Object>> fileData, TableInfo tableInfo, boolean autoFillDefaultColumns)
throws SQLException, ValidationException, ExperimentException
/** Insert the data into the database. Transaction is active. */
protected List<Map<String, Object>> insertRowData(
ExpData data,
User user,
Container container,
ExpRun run,
ExpProtocol protocol,
AssayProvider provider,
Domain dataDomain,
List<Map<String, Object>> fileData,
TableInfo tableInfo,
boolean autoFillDefaultColumns
) throws SQLException, ValidationException, ExperimentException
{
OntologyManager.UpdateableTableImportHelper importHelper = new SimpleAssayDataImportHelper(data);
if (provider.isPlateMetadataEnabled(protocol))
{
AssayPlateMetadataService svc = AssayPlateMetadataService.getService(PlateMetadataDataHandler.DATA_TYPE);
if (svc != null)
{
importHelper = svc.getImportHelper(container, user, run, data, protocol, provider);
}
}
importHelper = AssayPlateMetadataService.get().getImportHelper(container, user, run, data, protocol, provider);

if (tableInfo instanceof UpdateableTableInfo)
{
return OntologyManager.insertTabDelimited(tableInfo, container, user, importHelper, fileData, autoFillDefaultColumns, LOG);
}
else
{
Integer id = OntologyManager.ensureObject(container, data.getLSID());
List<String> lsids = OntologyManager.insertTabDelimited(container, user, id,
importHelper, dataDomain, fileData, false);
// TODO: Add LSID values into return value rows
return fileData;
}

Integer id = OntologyManager.ensureObject(container, data.getLSID());
OntologyManager.insertTabDelimited(container, user, id, importHelper, dataDomain, fileData, false);

return fileData;
}

protected abstract boolean shouldAddInputMaterials();
Expand Down
6 changes: 1 addition & 5 deletions api/src/org/labkey/api/assay/DefaultAssayRunCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,6 @@

import static java.util.Collections.unmodifiableCollection;

/**
* User: jeckels
* Date: Oct 12, 2011
*/
public class DefaultAssayRunCreator<ProviderType extends AbstractAssayProvider> implements AssayRunCreator<ProviderType>
{
private static final Logger LOG = LogManager.getLogger(DefaultAssayRunCreator.class);
Expand Down Expand Up @@ -164,7 +160,7 @@ public Pair<ExpExperiment, ExpRun> saveExperimentRun(

exp = saveExperimentRun(context, exp, run, false);

// re-fetch the run after is has been fully constructed
// re-fetch the run after it has been fully constructed
run = ExperimentService.get().getExpRun(run.getRowId());

context.uploadComplete(run);
Expand Down
5 changes: 0 additions & 5 deletions api/src/org/labkey/api/assay/SimpleAssayDataImportHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,13 @@

package org.labkey.api.assay;

import org.labkey.api.data.Parameter;
import org.labkey.api.data.ParameterMapStatement;
import org.labkey.api.exp.OntologyManager;
import org.labkey.api.exp.api.ExpData;
import org.labkey.api.query.ValidationException;

import java.util.Map;

/**
* User: jeckels
* Date: Jul 23, 2007
*/
public class SimpleAssayDataImportHelper implements OntologyManager.ImportHelper, OntologyManager.UpdateableTableImportHelper
{
private int _id = 0;
Expand Down
69 changes: 42 additions & 27 deletions api/src/org/labkey/api/assay/plate/AssayPlateMetadataService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONObject;
import org.labkey.api.assay.AssayDataType;
import org.labkey.api.assay.AssayProvider;
import org.labkey.api.data.Container;
import org.labkey.api.data.ContainerManager;
Expand All @@ -15,29 +14,23 @@
import org.labkey.api.exp.api.ExpRun;
import org.labkey.api.exp.property.Domain;
import org.labkey.api.security.User;
import org.labkey.api.services.ServiceRegistry;
import org.labkey.api.settings.ExperimentalFeatureService;
import org.labkey.api.util.Pair;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public interface AssayPlateMetadataService
{
String PLATE_TEMPLATE_COLUMN_NAME = "PlateTemplate";
String PLATE_SET_COLUMN_NAME = "PlateSet";
Map<AssayDataType, AssayPlateMetadataService> _handlers = new HashMap<>();
String EXPERIMENTAL_APP_PLATE_SUPPORT = "experimental-app-plate-support";

static void registerService(AssayDataType dataType, AssayPlateMetadataService handler)
static void setInstance(AssayPlateMetadataService serviceImpl)
{
if (dataType != null)
{
_handlers.put(dataType, handler);
}
else
throw new RuntimeException("The specified assay data type is null");
ServiceRegistry.get().registerService(AssayPlateMetadataService.class, serviceImpl);
}

static boolean isExperimentalAppPlateEnabled()
Expand All @@ -53,10 +46,9 @@ static boolean isBiologicsFolder(Container container)
return false;
}

@Nullable
static AssayPlateMetadataService getService(AssayDataType dataType)
static AssayPlateMetadataService get()
{
return _handlers.get(dataType);
return ServiceRegistry.get().getService(AssayPlateMetadataService.class);
}

/**
Expand All @@ -75,17 +67,33 @@ static AssayPlateMetadataService getService(AssayDataType dataType)
* @param inserted the inserted result data
* @param rowIdToLsidMap a map of result data rowIds to result data lsids
*/
void addAssayPlateMetadata(ExpData resultData, Map<String, MetadataLayer> plateMetadata, Container container, User user, ExpRun run, AssayProvider provider,
ExpProtocol protocol, List<Map<String, Object>> inserted, Map<Integer, String> rowIdToLsidMap) throws ExperimentException;
void addAssayPlateMetadata(
ExpData resultData,
Map<String, MetadataLayer> plateMetadata,
Container container,
User user,
ExpRun run,
AssayProvider provider,
ExpProtocol protocol,
List<Map<String, Object>> inserted,
Map<Integer, String> rowIdToLsidMap
) throws ExperimentException;

/**
* Merges the results data with the plate metadata to produce a single row map
*
* @return the merged rows
*/
List<Map<String, Object>> mergePlateMetadata(Container container, User user, Lsid plateLsid, Integer plateSetId,
List<Map<String, Object>> rows, @Nullable Map<String, MetadataLayer> plateMetadata,
AssayProvider provider, ExpProtocol protocol) throws ExperimentException;
List<Map<String, Object>> mergePlateMetadata(
Container container,
User user,
Lsid plateLsid,
Integer plateSetId,
List<Map<String, Object>> rows,
@Nullable Map<String, MetadataLayer> plateMetadata,
AssayProvider provider,
ExpProtocol protocol
) throws ExperimentException;

/**
* Methods to create the metadata model from either a JSON object or a file object
Expand All @@ -98,22 +106,29 @@ List<Map<String, Object>> mergePlateMetadata(Container container, User user, Lsi
* well as cases where plate identifiers have not been supplied.
*/
List<Map<String, Object>> parsePlateData(
Container container,
User user,
AssayProvider provider,
ExpProtocol protocol,
Integer plateSetId,
File dataFile,
List<Map<String, Object>> data,
Pair<String, Boolean> plateIdAdded
Container container,
User user,
AssayProvider provider,
ExpProtocol protocol,
Integer plateSetId,
File dataFile,
List<Map<String, Object>> data,
Pair<String, Boolean> plateIdAdded
) throws ExperimentException;

/**
* Returns an import helper to help join assay results data to well data and metadata that is associated
* with the plate used in the assay run import
*/
@NotNull
OntologyManager.UpdateableTableImportHelper getImportHelper(Container container, User user, ExpRun run, ExpData data, ExpProtocol protocol, AssayProvider provider) throws ExperimentException;
OntologyManager.UpdateableTableImportHelper getImportHelper(
Container container,
User user,
ExpRun run,
ExpData data,
ExpProtocol protocol,
AssayProvider provider
) throws ExperimentException;

interface MetadataLayer
{
Expand Down
Loading