Skip to content

Commit

Permalink
Fix #102
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Liddell committed Mar 29, 2019
1 parent 7df290a commit e2ae8b6
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 62 deletions.
64 changes: 44 additions & 20 deletions +jrclust/+curate/@CurateController/saveFiles.m
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,63 @@
obj.cRes.curatedOn = now();

res_ = jrclust.utils.mergeStructs(obj.res, obj.cRes);
% don't save these large fields
res_ = rmfield(res_, 'hClust');

hClust = obj.hClust;

res_.initialClustering = hClust.initialClustering;
res_.spikeClusters = hClust.spikeClusters;

% fieldnames contained in dRes or sRes
dsFields = union(fieldnames(hClust.dRes), fieldnames(hClust.sRes));
% fieldnames from hClust which are not in dRes or sRes
hClustOnly = setdiff(fieldnames(hClust), dsFields);
for i = 1:numel(hClustOnly)
fn = hClustOnly{i};
% hClust fields take precedence
res_.(fn) = hClust.(fn);
end

% don't save these fields
if isfield(res_, 'spikesRaw')
res_ = rmfield(res_, 'spikesRaw');
end
if isfield(res_, 'spikesRawVolt')
res_ = rmfield(res_, 'spikesRawVolt');
end
if isfield(res_, 'spikesFilt')
res_ = rmfield(res_, 'spikesFilt');
end
if isfield(res_, 'spikesFiltVolt')
res_ = rmfield(res_, 'spikesFiltVolt');
end
if isfield(res_, 'spikesFilt2')
res_ = rmfield(res_, 'spikesFilt2');
end
if isfield(res_, 'spikesFilt3')
res_ = rmfield(res_, 'spikesFilt3');
end
if isfield(res_, 'spikeFeatures')
res_ = rmfield(res_, 'spikeFeatures');
end
if isfield(res_, 'nClusters')
res_ = rmfield(res_, 'nClusters');
end
if isfield(res_, 'nEdits')
res_ = rmfield(res_, 'nEdits');
end
if isfield(res_, 'unitFields')
res_ = rmfield(res_, 'unitFields');
end
if isfield(res_, 'hRecs')
res_ = rmfield(res_, 'hRecs');
end

% don't save this stuff twice
restoreFields = struct(); % restore these fields to hClust after saving
restoreFields.dRes = res_.hClust.dRes;
res_.hClust.dRes = [];

restoreFields.sRes = res_.hClust.sRes;
res_.hClust.sRes = [];

hMsg = jrclust.utils.qMsgBox('Saving... (this closes automatically)', 0, 1);
hBox = jrclust.utils.qMsgBox('Saving... (this closes automatically)', 0, 1);
jrclust.utils.saveStruct(res_, obj.hCfg.resFile);

% restore fields to carry on
if ~obj.isEnding
restoreFieldNames = fieldnames(restoreFields);
for i = 1:numel(restoreFieldNames)
fn = restoreFieldNames{i};
obj.hClust.(fn) = restoreFields.(fn);
end
end

success = 1;
jrclust.utils.tryClose(hMsg);
jrclust.utils.tryClose(hBox);
elseif strcmp(dlgAns, 'No')
success = 1;
else
Expand Down
4 changes: 2 additions & 2 deletions +jrclust/+interfaces/@Clustering/Clustering.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
end

%% SORTING DATA (MUTABLE)
properties (SetAccess=protected, SetObservable)
properties (SetObservable)
clusterCentroids; % centroids of clusters on the probe
clusterNotes; % notes on clusters
clusterSites; % mode site per cluster
Expand Down Expand Up @@ -46,7 +46,7 @@
end

%% QUALITY METRICS
properties (SetAccess=protected, SetObservable)
properties (SetObservable)
unitPeaks; % minimum voltage of mean filtered waveforms at peak site, per cluster
unitPeaksRaw; % minimum voltage (uV) of mean raw waveforms at peak site, per cluster
unitPeakSites; % sites on which unitPeaks occur
Expand Down
9 changes: 6 additions & 3 deletions +jrclust/+sort/@DensityPeakClustering/DensityPeakClustering.m
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,16 @@
end

% rhoCuts
function rc = get.rhoCuts(obj)
function val = get.rhoCuts(obj)
if isfield(obj.sRes, 'rhoCutSite')
rc = obj.sRes.rhoCutSite;
val = obj.sRes.rhoCutSite;
else
rc = [];
val = [];
end
end
function set.rhoCuts(obj, val)
obj.sRes.rhoCutSite = val;
end

% waveformSim/mrWavCor
function ss = get.mrWavCor(obj)
Expand Down
4 changes: 3 additions & 1 deletion +jrclust/+sort/@TemplateClustering/TemplateClustering.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
obj.dRes = dRes;
obj.hCfg = hCfg;

obj.spikeClusters = sRes.spikeClusters;
if isfield(sRes, 'spikeClusters')
obj.spikeClusters = sRes.spikeClusters;
end

obj.clearNotes();
obj.refresh(1, []);
Expand Down
24 changes: 13 additions & 11 deletions +jrclust/+sort/@TemplateClustering/refresh.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,22 @@ function refresh(obj, doRemoveEmpty, updateMe)
obj.templatesByCluster = arrayfun(@(iCluster) unique(obj.spikeTemplates(obj.spikesByCluster{iCluster})), ...
1:obj.nClusters, 'UniformOutput', 0);

templateSim_ = zeros(obj.nClusters);
for iCluster = 1:obj.nClusters
iTemplates = obj.templatesByCluster{iCluster}; % unique template indices for spikes in this cluster
if ~isempty(obj.nClusters)
templateSim_ = zeros(obj.nClusters);
for iCluster = 1:obj.nClusters
iTemplates = obj.templatesByCluster{iCluster}; % unique template indices for spikes in this cluster

% compute cluster sim score, Phy style
sims = max(obj.sRes.simScore(iTemplates, :), [], 1);
% compute cluster sim score, Phy style
sims = max(obj.sRes.simScore(iTemplates, :), [], 1);

for jCluster = iCluster:obj.nClusters
jTemplates = obj.templatesByCluster{jCluster};
templateSim_(iCluster, jCluster) = max(sims(jTemplates));
templateSim_(jCluster, iCluster) = templateSim_(iCluster, jCluster);
for jCluster = iCluster:obj.nClusters
jTemplates = obj.templatesByCluster{jCluster};
templateSim_(iCluster, jCluster) = max(sims(jTemplates));
templateSim_(jCluster, iCluster) = templateSim_(iCluster, jCluster);
end
end
end

obj.templateSim = templateSim_;
obj.templateSim = templateSim_;
end
end

23 changes: 23 additions & 0 deletions @JRC/loadFiles.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function loadFiles(obj)
spikesFilt = [];
end

% load spikeFeatures
if isfield(res_, 'featuresShape')
obj.hCfg.updateLog('loadFeatures', sprintf('Loading %s', obj.hCfg.featuresFile), 1, 0);
spikeFeatures = readBin(obj.hCfg.featuresFile, res_.featuresShape, '*single');
Expand Down Expand Up @@ -82,6 +83,28 @@ function loadFiles(obj)

% supply hClust with our own hCfg
res_.hClust.hCfg = obj.hCfg;
elseif isfield(res_, 'spikeTemplates') % create a new TemplateClustering
hClust = jrclust.sort.TemplateClustering(struct(), struct(), obj.hCfg);
fieldNames = fieldnames(res_);
for i = 1:numel(fieldNames)
fn = fieldNames{i};
if isprop(hClust, fn)
hClust.(fn) = res_.(fn);
end
end

res_.hClust = hClust;
elseif isfield(res_, 'spikeClusters')
hClust = jrclust.sort.DensityPeakClustering(struct(), struct(), obj.hCfg);
fieldNames = fieldnames(res_);
for i = 1:numel(fieldNames)
fn = fieldNames{i};
if isprop(hClust, fn)
hClust.(fn) = res_.(fn);
end
end

res_.hClust = hClust;
end

if isfield(res_, 'hRecs') % don't try to load recordings
Expand Down
54 changes: 30 additions & 24 deletions @JRC/saveRes.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,39 @@ function saveRes(obj, forceOverwrite)
obj.hCfg.updateLog('saveRes', sprintf('Saving results to %s', obj.hCfg.resFile), 1, 0);
% save everything else (don't save spikesRaw, spikesFilt,
% spikeFeatures inside hClust)
restoreFields = struct(); % restore these fields to hClust after saving
% don't save these large fields
res_ = rmfield(obj.res, 'hClust');

if isfield(obj.res, 'hClust')
restoreFields.dRes = obj.res.hClust.dRes;
obj.res.hClust.dRes = [];
hClust = obj.res.hClust;

restoreFields.sRes = obj.res.hClust.sRes;
obj.res.hClust.sRes = [];
res_.initialClustering = hClust.initialClustering;
res_.spikeClusters = hClust.spikeClusters;

% fieldnames contained in dRes and sRes
dsFields = union(fieldnames(restoreFields.dRes), fieldnames(restoreFields.sRes));
% fieldnames contained in dRes or sRes
dsFields = union(fieldnames(hClust.dRes), fieldnames(hClust.sRes));
% fieldnames from hClust which are not in dRes or sRes
hClustOnly = setdiff(fieldnames(obj.res.hClust), dsFields);
% any redundancies with res?
intersectFields = intersect(fieldnames(obj.res), hClustOnly);
for i = 1:numel(intersectFields)
fn = intersectFields{i};
if jrclust.utils.isEqual(obj.res.(fn), obj.res.hClust.(fn))
restoreFields.(fn) = obj.res.hClust.(fn);
obj.res.hClust.(fn) = [];
end
hClustOnly = setdiff(fieldnames(hClust), dsFields);
for i = 1:numel(hClustOnly)
fn = hClustOnly{i};
% hClust fields take precedence
res_.(fn) = hClust.(fn);
end
end

% don't save these large fields
res_ = obj.res;
% don't save these fields
if isfield(res_, 'spikesRaw')
res_ = rmfield(res_, 'spikesRaw');
end
if isfield(res_, 'spikesRawVolt')
res_ = rmfield(res_, 'spikesRawVolt');
end
if isfield(res_, 'spikesFilt')
res_ = rmfield(res_, 'spikesFilt');
end
if isfield(res_, 'spikesFiltVolt')
res_ = rmfield(res_, 'spikesFiltVolt');
end
if isfield(res_, 'spikesFilt2')
res_ = rmfield(res_, 'spikesFilt2');
end
Expand All @@ -60,17 +62,21 @@ function saveRes(obj, forceOverwrite)
if isfield(res_, 'spikeFeatures')
res_ = rmfield(res_, 'spikeFeatures');
end
if isfield(res_, 'nClusters')
res_ = rmfield(res_, 'nClusters');
end
if isfield(res_, 'nEdits')
res_ = rmfield(res_, 'nEdits');
end
if isfield(res_, 'unitFields')
res_ = rmfield(res_, 'unitFields');
end
if isfield(res_, 'hRecs')
res_ = rmfield(res_, 'hRecs');
end

jrclust.utils.saveStruct(res_, obj.hCfg.resFile);

restoreFieldNames = fieldnames(restoreFields);
for i = 1:numel(restoreFieldNames)
fn = restoreFieldNames{i};
obj.res.hClust.(fn) = restoreFields.(fn);
end
obj.res.hClust = hClust;

obj.hCfg.updateLog('saveRes', sprintf('Results saved to %s', obj.hCfg.resFile), 0, 1);
end
2 changes: 1 addition & 1 deletion CHANGELOG.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- Allow user to select exploratory clustering algorithm in main split.
- Allow user to split in FigProj.

- hClust is no longer saved to _res.mat. Now all fields are available without having a copy of JRCLUST installed.

27 Mar 2019

Expand Down

0 comments on commit e2ae8b6

Please sign in to comment.