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

Ensure Units Immutability #730

Merged
merged 4 commits into from
Apr 5, 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
51 changes: 32 additions & 19 deletions pyflask/manageNeuroconv/manage_neuroconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
}

EXTRA_SORTING_INTERFACE_PROPERTIES = ["unit_name", *EXTRA_INTERFACE_PROPERTIES.keys()]
EXTRA_SORTING_INTERFACE_PROPERTIES = ["unit_id", *EXTRA_INTERFACE_PROPERTIES.keys()]

SORTING_INTERFACE_PROPERTIES_TO_RECAST = {
"quality": {
Expand All @@ -52,14 +52,20 @@
}

SORTING_INTERFACE_PROPERTY_OVERRIDES = {
"unit_name": {"description": "The unique name for the unit", "data_type": "str"},
"unit_id": {"description": "The unique ID for this unit", "data_type": "str"},
"brain_area": {
"description": "The brain area where the unit is located.",
**EXTRA_INTERFACE_PROPERTIES["brain_area"],
},
**SORTING_INTERFACE_PROPERTIES_TO_RECAST,
}

# NOTE: No need to show this if it isn't editable
del SORTING_INTERFACE_PROPERTY_OVERRIDES["brain_area"]
brain_area_idx = EXTRA_SORTING_INTERFACE_PROPERTIES.index("brain_area")
EXTRA_SORTING_INTERFACE_PROPERTIES.pop(brain_area_idx)


EXCLUDED_SORTING_INTERFACE_PROPERTIES = ["location", "spike_times", "electrodes"] # Not validated

# NOTE: These are the only accepted dtypes...
Expand Down Expand Up @@ -721,19 +727,22 @@ def update_conversion_progress(**kwargs):
has_units = "Units" in ecephys_metadata

if has_units:
shared_units_columns = ecephys_metadata["UnitColumns"]
for interface_name, interface_unit_results in ecephys_metadata["Units"].items():
interface = converter.data_interface_objects[interface_name]

update_sorting_properties_from_table_as_json(
interface,
unit_table_json=interface_unit_results,
unit_column_info=shared_units_columns,
)

ecephys_metadata["UnitProperties"] = [
{"name": entry["name"], "description": entry["description"]} for entry in shared_units_columns
]
## NOTE: Currently do not allow editing units properties
# shared_units_columns = ecephys_metadata["UnitColumns"]
# for interface_name, interface_unit_results in ecephys_metadata["Units"].items():
# interface = converter.data_interface_objects[interface_name]

# update_sorting_properties_from_table_as_json(
# interface,
# unit_table_json=interface_unit_results,
# unit_column_info=shared_units_columns,
# )

# ecephys_metadata["UnitProperties"] = [
# {"name": entry["name"], "description": entry["description"]} for entry in shared_units_columns
# ]

del ecephys_metadata["Units"]
del ecephys_metadata["UnitColumns"]

Expand Down Expand Up @@ -1232,9 +1241,12 @@ def get_unit_table_json(interface) -> List[Dict[str, Any]]:

for property_name in properties:

# Separate this so that unit_id and unit_name exist (LOOK FURTHER)
if property_name == "unit_name":
sorting_property_value = str(unit_id) # Insert unit_id as name (str)
if property_name == "unit_id":
sorting_property_value = str(unit_id) # Insert unit_id to view

# elif property_name == "unit_name":
# sorting_property_value = str(unit_id) # By default, unit_name is unit_id (str)

elif property_name in SORTING_INTERFACE_PROPERTY_OVERRIDES:
try:
sorting_property_value = SORTING_INTERFACE_PROPERTY_OVERRIDES[property_name][
Expand Down Expand Up @@ -1417,11 +1429,11 @@ def update_sorting_properties_from_table_as_json(
for entry_index, entry in enumerate(unit_table_json):
unit_properties = dict(entry) # copy

unit_id = unit_properties.pop("unit_name", None) # NOTE: Is called unit_name in the actual units table
unit_id = unit_properties.pop("unit_id", None) # NOTE: Is called unit_name in the actual units table

for property_name, property_value in unit_properties.items():

if property_name == "unit_name":
if property_name == "unit_id":
continue # Already controlling unit_id with the above variable

dtype = unit_column_data_types[property_name]
Expand All @@ -1433,4 +1445,5 @@ def update_sorting_properties_from_table_as_json(
key=property_name,
values=np.array([property_value], dtype=dtype),
ids=[int(unit_id)],
# ids=[unit_id]
)
13 changes: 9 additions & 4 deletions schemas/base-metadata.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ export const preprocessMetadataSchema = (schema: any = baseMetadataSchema, globa
ecephys.properties.Device.title = 'Devices'
ecephys.properties.ElectrodeGroup.title = 'Electrode Groups'

if (ecephys.properties.ElectrodeColumns) ecephys.properties.ElectrodeColumns.order = COLUMN_SCHEMA_ORDER
if (ecephys.properties.UnitProperties) ecephys.properties.UnitProperties.order = COLUMN_SCHEMA_ORDER
if (ecephys.properties.ElectrodeColumns) ecephys.properties.ElectrodeColumns.items.order = COLUMN_SCHEMA_ORDER
if (ecephys.properties.UnitColumns) ecephys.properties.UnitColumns.items.order = COLUMN_SCHEMA_ORDER


updateEcephysTable("Electrodes", copy, {
Expand All @@ -156,10 +156,15 @@ export const preprocessMetadataSchema = (schema: any = baseMetadataSchema, globa
order: ["channel_name", "group_name", "shank_electrode_number", ...UV_PROPERTIES]
})

// ecephys.properties["Units"].title = "Unit Summaries"
ecephys.properties["Units"].title = "Summarized Units"

updateEcephysTable("Units", copy, {
order: ["unit_name", "clu_id", "group_id"]
properties: {
clu_id: {
title: 'Cluster ID',
}
},
order: ["unit_id", "unit_name", "clu_id", "group_id"]
})

}
Expand Down
11 changes: 8 additions & 3 deletions src/renderer/src/stories/BasicTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export class BasicTable extends LitElement {
onLoaded,
onUpdate,
editable = true,
truncated = false,
} = {}) {
super();
this.name = name ?? "data_table";
Expand All @@ -147,7 +148,8 @@ export class BasicTable extends LitElement {
if (onStatusChange) this.onStatusChange = onStatusChange;
if (onLoaded) this.onLoaded = onLoaded;

this.editable = editable;
this.truncated = truncated;
this.editable = editable && !truncated;
}

#schema = {};
Expand Down Expand Up @@ -419,8 +421,6 @@ export class BasicTable extends LitElement {
}); // Only include data from schema
});

console.log(header, data, structuredData, this.data, this.#itemProps);

if (this.onUpdate) this.onUpdate([], data); // Update the whole table
}

Expand All @@ -431,6 +431,8 @@ export class BasicTable extends LitElement {
this.schema = this.schema; // Always update the schema
const entries = this.#itemProps;

if (this.truncated) this.data = this.data.slice(0, 5); // Limit to 5 rows when truncated

// Add existing additional properties to the entries variable if necessary
if (this.#itemSchema.additionalProperties) {
Object.values(this.data).reduce((acc, v) => {
Expand Down Expand Up @@ -535,6 +537,9 @@ export class BasicTable extends LitElement {
>
</div>`
: ""}
${this.truncated
? html`<p style="margin: 0; width: 100%; text-align: center; font-size: 150%;">...</p>`
: ""}
${description
? html`<p style="margin: 0; margin-top: 10px">
<small style="color: gray;">${description}</small>
Expand Down
36 changes: 21 additions & 15 deletions src/renderer/src/stories/pages/guided-mode/data/GuidedMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const parentTableRenderConfig = {
return true;
},
Units: (metadata) => {
metadata.editable = false;
metadata.truncated = true;
metadata.schema.description = "Update unit information directly on your source data.";
return true;
},
Expand Down Expand Up @@ -60,21 +60,27 @@ const tableRenderConfig = {
});
},
UnitColumns: function (metadata) {
const aggregateRequirements = getAggregateRequirements.call(this, ["Ecephys", "Units"]);
metadata.editable = false;
console.log("Column metadata", metadata);
metadata.schema.description = "Update unit information directly on your source data.";

return new SimpleTable({
...metadata,
contextOptions: {
row: {
add: false,
remove: false,
},
},
editable: {
name: (value) => !aggregateRequirements.has(value),
data_type: (_, row) => !aggregateRequirements.has(row.name),
},
});
return true;

// const aggregateRequirements = getAggregateRequirements.call(this, ["Ecephys", "Units"]);
//
// return new SimpleTable({
// ...metadata,
// contextOptions: {
// row: {
// add: false,
// remove: false,
// },
// },
// editable: {
// name: (value) => !aggregateRequirements.has(value),
// data_type: (_, row) => !aggregateRequirements.has(row.name),
// },
// });
},
};

Expand Down
Loading