Skip to content

Commit

Permalink
AbDisc: Plate Templates (Part 1) (#5467)
Browse files Browse the repository at this point in the history
  • Loading branch information
labkey-nicka authored May 2, 2024
1 parent 06b9a3c commit 0981d1e
Show file tree
Hide file tree
Showing 39 changed files with 1,932 additions and 1,502 deletions.
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

0 comments on commit 0981d1e

Please sign in to comment.