OSCR

Quantifying Correlogram Shape to Analyze Neuronal Firing Dynamics Recorded in TBI-on-a-Chip.

Code ↔ Paper

12 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 12 matches · 2 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § Methods › Correlogram Shape Quantification › Quantifying and Classifying Firing Pattern ↔ Analysis Execution/summarizeCorrelograms.m, lines 299–382 · score 0.97 · beta band, gamma band, theta band, delta band, 13–30 Hz, 8–12 Hz
  2. [2] § Methods › Correlogram Shape Quantification › Quantifying and Classifying Firing Pattern ↔ Analysis Execution/calculateCorrelogramMetrics.m, lines 1–147 · score 0.77 · uniform distribution, comparison signal, findpeaks, reference signal, loess, prominence
  3. [3] § Methods › Correlogram Shape Quantification › Quantifying and Classifying Signal Dependence ↔ Analysis Execution/calculateCorrelogramMetrics.m, lines 1–147 · score 0.74 · chi2cdf, chi squared, uniform distribution, cutoff, threshold, nonuniform
  4. [4] § Methods › Correlogram Shape Quantification › Quantifying and Classifying Firing Pattern ↔ Analysis Execution/plotCorrelograms.m, the whole file · a weak match · score 0.69 · smoothed correlogram, comparison signal, reference signal, loess, smoothdata, window
  5. [5] § Methods › Correlogram Shape Quantification ↔ Analysis Execution/summarizeCorrelograms.m, lines 893–987 · score 0.68 · follower strength classifications, nonuniform correlograms, uniformity classifications, Empty, leader, peak
  6. [6] § Methods › Algorithm Pipeline ↔ Analysis Execution/removeBadSignals.m, the whole file · a weak match · score 0.67 · noisy signals, eliminate signals, prompts, empty, rasters, plx
  7. [7] § Results › Correlogram Classification Heat Maps › Bicuculline ↔ Analysis Execution/summarizeCorrelograms.m, lines 204–238 · score 0.64 · fairly weak, fairly strong, strong leader, week, intermediate, follower
  8. [8] § Results › Summarizing Distributions by Classifying Correlogram Metrics ↔ Analysis Execution/summarizeCorrelograms.m, lines 204–238 · score 0.63 · follower nature, correlogram lead, strong leader, weak, fraction, classifies
  9. [9] § Methods › MEA Recording to Validate Algorithm Outputs ↔ Main_AnalyzeRecordingData.m, lines 16–24 · score 0.63 · bicuculline methiodide, impact injuries, permission, reused, publication, network
  10. [10] § Results › Violin Plots to Visualize Correlogram Metric Distributions ↔ Analysis Execution/Violin.m, lines 1–112 · score 0.62 · kernel density, Bastian, Bechtold, Hintze, Nelson, violinplot
  11. [11] § Results › Tracking Changes in Correlogram Classification › Alkalosis ↔ Analysis Execution/summarizeCorrelograms.m, lines 893–987 · score 0.61 · follower strength classification, nonuniform correlograms, correlogram classifications, leader, peaks
  12. [12] § Methods › Correlogram Shape Quantification › Quantifying and Classifying Firing Pattern ↔ Main_AnalyzeRecordingData.m, lines 59–75 · score 0.54 · bin widths, peak locations, threshold, Correlogram peak, classified, signals

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 987 lines · 61 KB · MIT · 5 matches

  1. function summarizeCorrelograms(sw, plotProps, AnalysisRegions, InjuryIndicies, ProcessedData, RecordingMetrics, Correlograms)
  2. %This function classifies correlograms based on metrics (uniformity, peak
  3. %count, area left of zero) and plots classification-related outputs
  4. %% Find where recording regions occurr relative to injuries or treatments
  5. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury/treatment in the history of the recording
  6. InjuryInds = zeros(3,InjuryIndicies.NumberOfInjuriesOrTreatments); %initialize array to save x coordinate of injuries/treatments for the violin plots (row 1) as well as the shading width (row 2) to indicate where the region occurred, and flag whether the injury occurred before the start of the recording (row 3)
  7. for j = 1: InjuryIndicies.NumberOfInjuriesOrTreatments %cycle through treatments/injuries
  8. relativeStartTimez = AnalysisRegions.Minutes-InjuryIndicies.InjuryStartMin(j); %get the time difference between each region and the injury start
  9. relativeEndTimez = AnalysisRegions.Minutes-InjuryIndicies.InjuryEndMin(j); %get the time difference between each region and the injury end
  10. endNegs = relativeEndTimez<0; %find where a region started (col 1) or ended (col 2) before an injury/treatment end
  11. endPos = relativeEndTimez>0; %find where a region started (col 1) or ended (col 2) after an injury/treatment end
  12. startNegs = relativeStartTimez<0; %find where a region started (col 1) or ended (col 2) before an injury/treatment end
  13. startNegSum = sum(startNegs,2); %if this sum is 2, then the region started and ended before the injury/treatment started.
  14. endNegSum = sum(endNegs,2); %if this sum is 2, then the region started and ended before the injury/treatment ended.
  15. endPosSum = sum(endPos,2); %if this sum is 2, then the region started and ended after the injury/treatment ended.
  16. simultaneousRegAndInj = endNegSum ~= startNegSum; %find whether any region was both in and out of the treatment range/simultaneous with the treatment
  17. if any(simultaneousRegAndInj) %if any row had both positive and negative times/occurred during an injury
  18. injuryIndj = find(simultaneousRegAndInj);
  19. shadeWidthj = 0.4;
  20. startFlagj = 0; %flag=1 if the injury occurred before the recording start
  21. else %otherwise the regions are either completely after or completely after the given injury/treatment
  22. locStartBetween = find(endNegSum==0,1,'first'); %find the first region after the injury/treatment
  23. locEndBetween = find(endPosSum==0,1,'last'); %find the last region before the injury/treatment
  24. if ~isempty(locEndBetween) && ~isempty(locStartBetween) %if the injury/treatment was during the recording
  25. injuryIndj = locStartBetween-(locStartBetween - locEndBetween)/2; %the index of the injury/treatment is between these two regions
  26. shadeWidthj = 0.03;
  27. startFlagj = 0; %flag=1 if the injury occurred before the recording start
  28. elseif isempty(locEndBetween) %if the treatment/injury was before the recording started or after all selected regions
  29. if InjuryIndicies.InjuryStartMin(j) > 0 %injury was after all analyzed regions
  30. injuryIndj = locStartBetween-.5; %the index of the injury/treatment is between these two regions
  31. shadeWidthj = 0.03;
  32. startFlagj = 0; %flag=1 if the injury occurred before the recording startstartFlagj = 0; %flag=1 if the injury occurred before the recording start
  33. else %otherwise injury or treatment before all regions
  34. injuryIndj = locStartBetween/2; %the index of the injury/treatment is between these two regions
  35. if injuryIndj == 0.5; injuryIndj = 0.3; end %shift further from violins if injury/treatment before recording start
  36. shadeWidthj = 0.03;
  37. startFlagj = 1; %flag that the injury occurred before the recording start
  38. end
  39. elseif isempty(locStartBetween) %if the treatment/injury was after the region
  40. injuryIndj = locEndBetween+ 0.5; %the index of the injury/treatment is between these two regions
  41. shadeWidthj = 0.03;
  42. startFlagj = 0; %flag=1 if the injury occurred before the recording start
  43. end
  44. end %end check for simultaneous regions and injuries/treatments
  45. if length(injuryIndj)==1 %if there is only one region, or one space regions before which injury occurred..
  46. InjuryInds(1,j) = injuryIndj; %save the position of injury/treatment j in the list
  47. InjuryInds(2,j) = shadeWidthj; %save the width of the shading box for injury/treatment j in the list
  48. InjuryInds(3,j) = startFlagj; %save the width of the shading box for injury/treatment j in the list
  49. else %otherwise, the injury was administered over multiple regions...
  50. InjuryInds(1,j) = (injuryIndj(end)-injuryIndj(1))/2+injuryIndj(1); %save the position of injury/treatment j in the list
  51. numRegionsInvolved = length(injuryIndj); %get the number of regions in the treatment (to determine shading width)
  52. InjuryInds(2,j) = numRegionsInvolved/2; %save the width of the shading box for injury/treatment j in the list
  53. InjuryInds(3,j) = startFlagj; %save the width of the shading box for injury/treatment j in the list
  54. end
  55. end %end cycle through treatments/injuries
  56. end %end check if there was an injury/treatment
  57. %% Get recording zones
  58. %Zones = times relative to injury or treatment (i.e. before treatment, between treatments, after treatment)
  59. groupOrder = ProcessedData.RegionStats.groupOrder;
  60. timeRange = ProcessedData.RegionStats.timeRange;
  61. % Sort the analysis regions into each recording zone
  62. Zonez = zeros(1,AnalysisRegions.numRegions); %row = zone, column = region
  63. for zz = 1:size(timeRange,2) %cycle through zones...
  64. startTimeLimit = timeRange(1,zz); %the zone starts mid recording, so just look for anything from zone start to zone end
  65. endTimeLimit = timeRange(2,zz); %the zone ends mid recording as well
  66. %Find analysis regions within the zone
  67. %Note that any regions that are part of multiple zones are not marked as being part of either zone
  68. %however, such regions will be used as comparisons against those in the zone later
  69. afterZoneStart = AnalysisRegions.Seconds>=startTimeLimit; %find analysis region times after zone start
  70. afterZoneStart = sum(afterZoneStart,2)==2; %get analysis regions where the region start and end are both after the start of the zone
  71. beforeZoneEnd = AnalysisRegions.Seconds<=endTimeLimit; %find analysis region times before zone end
  72. beforeZoneEnd = sum(beforeZoneEnd,2)==2; %get analysis regions where the region start and end are both before the end of the zone
  73. inZoneInds = afterZoneStart&beforeZoneEnd; %find regions contained within the zone
  74. if ~any(inZoneInds==1) %if the zone is smaller than a single analysis region, ensure that those regions (where the treatmment is administered) are added to the zone
  75. disp([' Zone ' num2str(zz) ' (' char(groupOrder{zz}) ') began and ended in a single region or in the middle of two adjacent regions.'])
  76. afterZoneStart = AnalysisRegions.Seconds>=startTimeLimit; %find analysis region times after zone start
  77. afterZoneStart = sum(afterZoneStart,2)==1; %get analysis regions where the region start and end are both after the start of the zone
  78. beforeZoneEnd = AnalysisRegions.Seconds<=endTimeLimit; %find analysis region times before zone end
  79. beforeZoneEnd = sum(beforeZoneEnd,2)==1; %get analysis regions where the region start and end are both before the end of the zone
  80. zoneLimitz = find(afterZoneStart):find(beforeZoneEnd);
  81. inZoneInds = false(size(afterZoneStart)); inZoneInds(zoneLimitz) = true; %find regions contained within the zone
  82. end
  83. Zonez(inZoneInds) = zz; %mark which zone the region belongs to
  84. end %end cycle through zones
  85. numZones = length(unique(Zonez(Zonez>0))); %count the number of recording zones
  86. %% Get correlogram data arrays
  87. %Determine whether to exclude autocorrelograms from the analysis based on user preferences
  88. if plotProps.includeAutocorrelogramsInStatistics == 1 %if user wants to include autocorrelograms in the violins...
  89. b1 = zeros(size(RecordingMetrics.CorrelogramMetrics.Region1.leaderProbMat)); %include all indicies
  90. else %otherwise, only include crosscorrelograms in violins
  91. %get the autocorrelograms (same number as the signal count, unless only select references are specified)
  92. b1=eye(size(RecordingMetrics.CorrelogramMetrics.Region1.leaderProbMat)); %find the matrix diagonal/autocorrelograms
  93. end
  94. %If only selecting a subset of signals as the reference signal, take only the relevent indicies (of those comparisons only)
  95. b2=ones(ProcessedData.CellCount,ProcessedData.CellCount); b2(:,RecordingMetrics.CorrelogramMetrics.refIndicies)=0;
  96. b=(b1 & ~b2); autoCorNum = sum(b(:)); %count how many correlograms (if any) are being excluded
  97. %Initialize arrays
  98. leaderProbArray = zeros(ProcessedData.CellCount.*length(RecordingMetrics.CorrelogramMetrics.refIndicies)-autoCorNum,AnalysisRegions.numRegions);
  99. numPeaksArray = zeros(ProcessedData.CellCount.*length(RecordingMetrics.CorrelogramMetrics.refIndicies)-autoCorNum,AnalysisRegions.numRegions);
  100. uniformityArray = zeros(ProcessedData.CellCount.*length(RecordingMetrics.CorrelogramMetrics.refIndicies)-autoCorNum,AnalysisRegions.numRegions);
  101. uniformitypArray = zeros(ProcessedData.CellCount.*length(RecordingMetrics.CorrelogramMetrics.refIndicies)-autoCorNum,AnalysisRegions.numRegions);
  102. %For peak positions (which provide frequencies for any rhythmic activity), each region can have a different number of peaks. Therefore, regions with less than the maximum number of peaks need to be padded with dummy numbers so that they are all the same size for violin plot
  103. MaxNumPk = 0;
  104. for rr = 1:AnalysisRegions.numRegions %find the maximum possible number of peaks for all regions
  105. reg_field = strcat('Region',num2str(rr)); %convert the name of the region to a variable name to call the correct correlogram substructure
  106. MaxNumPk = max(MaxNumPk,max(RecordingMetrics.CorrelogramMetrics.(reg_field).numberOfCorrelogramPeaks));
  107. end
  108. PkArray = NaN(MaxNumPk,AnalysisRegions.numRegions); %initialize peak frequency array
  109. SourceCorrelogram = zeros(size(PkArray)); %initialize array to store an ID for the correlogram in which each peak is located
  110. %% Populate the correlogram arrays for each analysis region
  111. for rr = 1:AnalysisRegions.numRegions %for each region...
  112. reg_field = strcat('Region',num2str(rr)); %get the region name to access the data structure
  113. if plotProps.includeAutocorrelogramsInStatistics == 1 %if user wants to include autocorrelograms in the violins
  114. leaderProbArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).leaderProb'; %store the metric in the data structure
  115. numPeaksArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).numberOfCorrelogramPeaks'; %store the metric in the data structure
  116. uniformityArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).uniformityTest'; %store the metric in the data structure
  117. b1 = zeros(size(RecordingMetrics.CorrelogramMetrics.(reg_field).leaderProbMat));
  118. else
  119. b1=eye(size(RecordingMetrics.CorrelogramMetrics.(reg_field).leaderProbMat)); %find the matrix diagonal/autocorrelograms
  120. end
  121. b2=ones(ProcessedData.CellCount,ProcessedData.CellCount); b2(:,RecordingMetrics.CorrelogramMetrics.refIndicies)=0;
  122. b = b1 | b2; %get only the reference signals you want (if specific references were selected);
  123. %get all cross-correlogram properties (not including autocorrelograms or excluded references if specified)
  124. leaderProbArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).leaderProbMat(~b); %store the metric in the data structure
  125. numPeaksArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).numberOfCorrelogramPeaks(~b); %store the metric in the data structure
  126. uniformityArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).uniformityTest(~b); %store the metric in the data structure
  127. uniformitypArray(:,rr) = RecordingMetrics.CorrelogramMetrics.(reg_field).uniformityTestPValue(~b); %store the metric in the data structure
  128. if plotProps.classifyPeakTimesAsFrequencies == 1 %if classifying peak times according to frequency (Hz, f = 1/t)...
  129. PeakLocationArray = cell2mat(cellfun(@(x) 1./abs(x), RecordingMetrics.CorrelogramMetrics.(reg_field).correlogramPeakLocations(~b),'UniformOutput',false))'; %list peak frequencies
  130. PeakAtZero = isinf(PeakLocationArray); PeakLocationArray = PeakLocationArray(~PeakAtZero); %remove peaks that occurred at t=0, which have f = 1/0 = infinity (which is not physiological)
  131. PkArray(1:length(PeakLocationArray),rr) = PeakLocationArray; %store the metric in the data structure
  132. else %otherwise classify peak times accorsing to time (s)
  133. PeakLocationArray = cell2mat(cellfun(@(x) abs(x), RecordingMetrics.CorrelogramMetrics.(reg_field).correlogramPeakLocations(~b),'UniformOutput',false))'; %list peak frequencies
  134. PkArray(1:length(PeakLocationArray),rr) = PeakLocationArray; %store the metric in the data structure
  135. end
  136. %Store the ID of the correlogram from which each peak originated
  137. startInd = 1; %start index for source correlogram IDs (since the number of peaks can be > 1 for any correlogram, the peak frequency array is larger than the correlogram arrays. Therefore, it is necessary to track which correlogram contained each peak)
  138. for i = 1:ProcessedData.CellCount^2 %cycle through correlograms...
  139. N = RecordingMetrics.CorrelogramMetrics.(reg_field).numberOfCorrelogramPeaks(i); %Get the number of correlogram peaks
  140. N2 = sum(isinf(1./(abs(RecordingMetrics.CorrelogramMetrics.(reg_field).correlogramPeakLocations{i})))); %determine if f = Inf (unphysiological) for any of the peaks
  141. if isnan(N) || N > N2 %if there is at least one peak not equal to infinity...
  142. if isnan(N) %set the value of N if the correlogram is empty
  143. N = 1; N2 = 0;
  144. end
  145. SourceCorrelogram(startInd:startInd+(N-N2)-1,rr) = i; %save correlogram source ID in the matrix
  146. startInd = startInd+(N-N2); %advance to the start for the next correlogram ID
  147. end %end check that there is at least one peak not equal to infinity
  148. end %end cycle through correlograms
  149. end %end cycle through regions
  150. PkArray(PkArray==0)=NaN;
  151. %% Classify leader/follower nature of the correlograms
  152. leaderProbGroupBoundaries = 0:.2:1;
  153. leaderClassificationNames = {'Weak', 'Fairly Weak', 'Intermediate', 'Fairly Strong', 'Strong'};
  154. NumberOfleaderClassificationGroups = length(leaderClassificationNames); %get all possible groups for nonempty correlograms
  155. fracInProbGroup = NaN(size(leaderProbGroupBoundaries,2)-1,AnalysisRegions.numRegions); %Row = grouping, Col = Recording Region
  156. LFGroupAssignments = NaN(size(leaderProbArray)); %initialize array to store leader/follower classifications
  157. StrongWeakClass = abs(leaderProbArray - 0.5)./0.5; %Bin into five categories of weak->strong leader/follower characteristic. A value of 1 is strong, 0 is weak
  158. for g = 1:length(leaderProbGroupBoundaries)-1
  159. %Get bounds on the probabilities in range
  160. a = leaderProbGroupBoundaries(g); b = leaderProbGroupBoundaries(g+1);
  161. %Find the values of how strong/week a given correlogram leads/follows within in the given range (a - b)
  162. if g == 1 %at the start of category listing, so pad the zero (lower group bound) to avoid machine/rounding error
  163. ProbInBin = (StrongWeakClass>=a-1 & StrongWeakClass<b); %find leader/follower strength classifications within the given range
  164. elseif b~=1 %as long as b is not the end of the list
  165. ProbInBin = (StrongWeakClass>=a & StrongWeakClass<b); %find leader/follower strength classifications within the given range
  166. else %otherwise, end of the category listing, so be sure to include the highest limit (don't reserve for the next group as with non-end elements of the categories)
  167. %at the start of category listing, so pad the 1 (upper group bound) to avoid machine/rounding error
  168. ProbInBin = (StrongWeakClass>=a & StrongWeakClass<=b+1); %find leader/follower strength classifications within the given range
  169. end
  170. LFGroupAssignments(ProbInBin) = g; %save the logical array marking which correlograms fall into which bin
  171. fracInProbGroup(g,1:end) = sum(ProbInBin,1); %sum up how many correlograms fit in the given bin
  172. end
  173. %Do not count correlograms with 0 events in the total
  174. EmptyCorrelograms = isnan(leaderProbArray); %Find correlograms with 0 events
  175. totalNumberOfCorrelograms = sum(~EmptyCorrelograms,1); %Get the actual/non-empty count
  176. fracInProbGroup = fracInProbGroup./totalNumberOfCorrelograms; %Get the fraction of correlograms in each bin
  177. %% Classify peak counts of the correlograms
  178. pkCountGroupBoundaries = min(numPeaksArray(:)):1:min(plotProps.maxPeakCountBeforeNoise,max(numPeaksArray(:))); %bin peak counts from the minimum to a user-specified maximum or the true maximum (whichever max value is smaller)
  179. pkCountNames = string(pkCountGroupBoundaries); %group names are just the peak count
  180. if plotProps.maxPeakCountBeforeNoise < max(numPeaksArray(:)) %the last group/peak count is a user-specified maximum, which may be smaller than the true maximum, so add "or more" to the name if this is the case
  181. pkCountNames{end} = strcat(pkCountNames{end},' or More');
  182. end
  183. NumberOfpkCountClassificationGroups = length(pkCountNames); %get all possible groups for nonempty correlograms
  184. fracInPeakGroup = NaN(size(pkCountGroupBoundaries,2)-1,AnalysisRegions.numRegions); %Row = grouping, Col = Recording Region
  185. PCGroupAssignments = NaN(size(numPeaksArray)); %initialize array to store peak count classifications
  186. for g = 1:length(pkCountGroupBoundaries)
  187. %Get bounds on the probabilities in range
  188. if g == length(pkCountGroupBoundaries)
  189. ProbInBin = numPeaksArray >= pkCountGroupBoundaries(g); %find correlograms with the given number of peaks or more if at the end of the group list
  190. else
  191. ProbInBin = numPeaksArray == pkCountGroupBoundaries(g); %find correlograms with the given number of peaks
  192. end
  193. PCGroupAssignments(ProbInBin) = g; %save the logical array marking which correlograms fall into which bin
  194. fracInPeakGroup(g,1:end) = sum(ProbInBin,1); %sum up how many correlograms fit in the given bin
  195. end
  196. %Do not count correlograms with 0 events in the total
  197. EmptyCorrelograms = isnan(numPeaksArray); %Find correlograms with 0 events
  198. totalNumberOfCorrelograms = sum(~EmptyCorrelograms,1); %Get the actual/non-empty count
  199. fracInPeakGroup = fracInPeakGroup./totalNumberOfCorrelograms; %Get the fraction of correlograms in each bin
  200. %% Uniformity is already classified as uniform and nonuniform, so just get the fraction of uniform and nonuniform in each data analysis region
  201. unifGroupBoundaries = [0 1];
  202. unifNames = {'Nonuniform','Uniform'};
  203. NumberOfunifClassificationGroups = length(unifGroupBoundaries); %get all possible groups for nonempty correlograms
  204. fracInUnifGroup = NaN(size(unifGroupBoundaries,2)-1,AnalysisRegions.numRegions); %Row = grouping, Col = Recording Region
  205. unifGroupAssignments = NaN(size(uniformityArray)); %initialize array to store peak count classifications
  206. for g = 1:length(unifGroupBoundaries)
  207. %Get bounds on the probabilities in range
  208. ProbInBin = uniformityArray == unifGroupBoundaries(g); %find correlograms with the given uniformity classification
  209. unifGroupAssignments(ProbInBin) = g; %save the logical array marking which correlograms fall into which bin
  210. fracInUnifGroup(g,1:end) = sum(ProbInBin,1); %sum up how many correlograms fit in the given bin
  211. end
  212. %Do not count correlograms with 0 events in the total
  213. EmptyCorrelograms = isnan(uniformityArray); %Find correlograms with 0 events
  214. totalNumberOfCorrelograms = sum(~EmptyCorrelograms,1); %Get the actual/non-empty count
  215. fracInUnifGroup = fracInUnifGroup./totalNumberOfCorrelograms; %Get the fraction of correlograms in each bin
  216. %% Classify correlogram peak times or peak frequencies
  217. % EEG Categories (if classifying by frequency)
  218. % Delta: f < 4
  219. % Theta: 4 <= f <= 7
  220. % Alpha: 8 <= f <= 12
  221. % Beta: 13 <= f <= 30
  222. % Gamma: f > 32
  223. if plotProps.classifyPeakTimesAsFrequencies == 1 %if classifying peak times according to frequency (Hz, f = 1/t)...
  224. startF = [0 4 7 8 12 13 30 32]; %list the minimum frequency of each category
  225. endF = [4 7 8 12 13 30 32 max(PkArray(:))+10]; %list the maximum frequency of each category
  226. freqClassificationNames = {'Delta Band (<4 Hz)', 'Theta Band (4-7 Hz)', 'Between Theta and Alpha (7-8 Hz)', 'Alpha Band (8-12 Hz)', 'Between Alpha and Beta (12-13 Hz)', 'Beta Band (13-30 Hz)', 'Between Beta and Gamma (30-32 Hz)', 'Gamma Band (>32 Hz)'};
  227. NumberOfFreqClassificationGroups = length(freqClassificationNames); %count the number of frequency categories
  228. else
  229. stpowr = [-Inf floor(log10(Correlograms.CorrelogramBins(end)-Correlograms.CorrelogramBins(end-1))):1:ceil(log10(max(PkArray(:))))-1]; %get the log10 power of time bin starts
  230. startF = 10.^stpowr; %list the minimum time of each category
  231. endpowr = [floor(log10(Correlograms.CorrelogramBins(end)-Correlograms.CorrelogramBins(end-1))):1:ceil(log10(max(PkArray(:))))]; %get the log10 power of time bin ends
  232. endF = 10.^endpowr; %list the maximum time of each category
  233. freqClassificationNames = repmat({' '},1,length(stpowr)); %initialize array to save time grouping names
  234. for i = 1:length(stpowr)
  235. if i == 1; ind = i+1; else; ind = i; end %get index to access the start time name
  236. %get the start and end time strings
  237. if stpowr(ind) == -12; sttstr = '1 picosecond'; elseif stpowr(ind) == -11; sttstr = '10 picoseconds'; elseif stpowr(ind) == -10; sttstr = '100 picoseconds'; elseif stpowr(ind) == -9; sttstr = '1 nanosecond'; elseif stpowr(ind) == -8; sttstr = '10 nanoseconds'; elseif stpowr(ind) == -7; sttstr = '100 nanoseconds'; elseif stpowr(ind) == -6; sttstr = '1 microsecond'; elseif stpowr(ind) == -5; sttstr = '10 microseconds'; elseif stpowr(ind) == -4; sttstr = '100 microseconds'; elseif stpowr(ind) == -3; sttstr = '1 millisecond'; elseif stpowr(ind) == -2; sttstr = '10 milliseconds'; elseif stpowr(ind) == -1; sttstr = '100 milliseconds'; elseif stpowr(ind) == 0; sttstr = '1 second'; elseif stpowr(ind) == 1; sttstr = '10 seconds'; elseif stpowr(ind) == 2; sttstr = '100 seconds'; elseif stpowr(ind) == 3; sttstr = '1,000 seconds'; elseif stpowr(ind) == 4; sttstr = '10,000 seconds'; elseif stpowr(ind) == 5; sttstr = '100,000 seconds'; elseif stpowr(ind) == 6; sttstr = '1,000,000 seconds'; end
  238. if endpowr(i) == -12; endtstr = '1 picosecond'; elseif endpowr(i) == -11; endtstr = '10 picoseconds'; elseif endpowr(i) == -10; endtstr = '100 picoseconds'; elseif endpowr(i) == -9; endtstr = '1 nanosecond'; elseif endpowr(i) == -8; endtstr = '10 nanoseconds'; elseif endpowr(i) == -7; endtstr = '100 nanoseconds'; elseif endpowr(i) == -6; endtstr = '1 microsecond'; elseif endpowr(i) == -5; endtstr = '10 microseconds'; elseif endpowr(i) == -4; endtstr = '100 microseconds'; elseif endpowr(i) == -3; endtstr = '1 millisecond'; elseif endpowr(i) == -2; endtstr = '10 milliseconds'; elseif endpowr(i) == -1; endtstr = '100 milliseconds'; elseif endpowr(i) == 0; endtstr = '1 second'; elseif endpowr(i) == 1; endtstr = '10 seconds'; elseif endpowr(i) == 2; endtstr = '100 seconds'; elseif endpowr(i) == 3; endtstr = '1,000 seconds'; elseif endpowr(i) == 4; endtstr = '10,000 seconds'; elseif endpowr(i) == 5; endtstr = '100,000 seconds'; elseif endpowr(i) == 6; endtstr = '1,000,000 seconds'; end
  239. if i == 1 %get the first entry in the categories
  240. tstr = [sttstr ' or less'];
  241. else %now get the non-start time ranges
  242. startchar = strfind(sttstr,' '); startchar = startchar(1); %get the index when the first number stops
  243. if startchar == 4 %if the first number is 100, use the full start name
  244. tstr = [sttstr ' - ' endtstr];
  245. else %otherwise, you only need to write the units once
  246. tstr = [sttstr(1:startchar-1) ' - ' endtstr];
  247. end
  248. end %end get the category range
  249. freqClassificationNames{i} = tstr; %save the category in the time classification name array
  250. end
  251. NumberOfFreqClassificationGroups = length(freqClassificationNames); %count the number of peak time categories
  252. end
  253. %Initialize peak frequency (or time) classification arrays
  254. fracInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = fraction of correlogram peaks in grouping, Col = Recording Region
  255. meanFreqInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = mean frequency within the given group, Col = Recording Region
  256. sdFreqInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = standard deviation in the frequency within the given group, Col = Recording Region
  257. seFreqInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = standard deviation in the frequency within the given group, Col = Recording Region
  258. minFreqInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = min frequency within the given group, Col = Recording Region
  259. maxFreqInFreqGroup = NaN(NumberOfFreqClassificationGroups,AnalysisRegions.numRegions); %Row = max frequency within the given group, Col = Recording Region
  260. FreqGroupAssignments = NaN(size(PkArray)); %initialize array to store peak frequency classifications
  261. for g = 1:NumberOfFreqClassificationGroups %for each classification grouping...
  262. if g == 1
  263. b = PkArray<= endF(g);
  264. else
  265. b = PkArray>startF(g) & PkArray <= endF(g); %find frequencies that fall within the given classification/grouping
  266. end
  267. FreqGroupAssignments(b) = g; %save the logical array marking peaks in the given classification
  268. fracInFreqGroup(g,:) = sum(b,1); %count how many correlogram peaks have a frequency in the given classification
  269. %min and max functions will return an empty array if no peaks are in group g for a given region. This interferes with MATLAB's indexing, so empty regions must be found and ignored for the min and max functions
  270. regionsWithPeaksInGroup = sum(b,1)>0; %make a logical indicating regions with at least one peak in the given classification group
  271. regionsWithGroup = 1:AnalysisRegions.numRegions; regionsWithGroup = regionsWithGroup(regionsWithPeaksInGroup); %list regions with at least one peak in the given classification group
  272. if any(regionsWithPeaksInGroup)
  273. meanFreqInFreqGroup(g,:) = cell2mat(arrayfun(@(col) mean(PkArray(b(:,col),col),'omitnan'),1:AnalysisRegions.numRegions,'UniformOutput',false)); % mean frequency of correlogram peaks in the given classification
  274. medianFreqInFreqGroup(g,:) = cell2mat(arrayfun(@(col) nanmedian(PkArray(b(:,col),col)),1:AnalysisRegions.numRegions,'UniformOutput',false)); % median frequency of correlogram peaks in the given classification
  275. sdFreqInFreqGroup(g,:) = cell2mat(arrayfun(@(col) std(PkArray(b(:,col),col),'omitnan'),1:AnalysisRegions.numRegions,'UniformOutput',false)); % standard deviation in the frequencies of correlogram peaks in the given classification
  276. seFreqInFreqGroup(g,:) = cell2mat(arrayfun(@(col) std(PkArray(b(:,col),col)/sqrt(length(b(:,col))),'omitnan'),1:AnalysisRegions.numRegions,'UniformOutput',false)); % standard error in the frequencies of correlogram peaks in the given classification
  277. minFreqInFreqGroup(g,regionsWithGroup) = cell2mat(arrayfun(@(col) min(PkArray(b(:,col),col),[],'omitnan'),regionsWithGroup,'UniformOutput',false)); % min frequency of correlogram peaks in the given classification
  278. maxFreqInFreqGroup(g,regionsWithGroup) = cell2mat(arrayfun(@(col) max(PkArray(b(:,col),col),[],'omitnan'),regionsWithGroup,'UniformOutput',false)); % max frequency of correlogram peaks in the given classification
  279. end
  280. end
  281. %Do not count correlograms with 0 events in the total for the % of peaks in each classification
  282. EmptyCorrelograms = isnan(PkArray) | PkArray == 0; %Find correlograms with 0 events
  283. totalNumberOfCorrelograms = sum(~EmptyCorrelograms,1); %Get the actual/non-empty count
  284. fracInFreqGroup = fracInFreqGroup./totalNumberOfCorrelograms; %Get the fraction of correlograms in each bin (sum of all rows for each column = 1)
  285. %% Make a structure containing indicies for each classification group
  286. %(for ease of accessing later/to prevent constantly using "find")
  287. for g = 1:NumberOfleaderClassificationGroups
  288. g_name = strcat('G',num2str(g));
  289. FindGroups.LeaderFollower.(g_name) = LFGroupAssignments==g;
  290. end
  291. for g = 1:NumberOfpkCountClassificationGroups
  292. g_name = strcat('G',num2str(g));
  293. FindGroups.PeakCount.(g_name) = PCGroupAssignments==g;
  294. end
  295. for g = 1:NumberOfunifClassificationGroups
  296. g_name = strcat('G',num2str(g));
  297. FindGroups.Unif.(g_name) = unifGroupAssignments==g;
  298. end
  299. for g = 1:NumberOfFreqClassificationGroups
  300. g_name = strcat('G',num2str(g));
  301. FindGroups.FreqClassification.(g_name) = FreqGroupAssignments==g;
  302. end
  303. %% Analyze classification changes between treatments/injuries
  304. %Get the probability that the correlogram now has its current classification, given the classification in the previous recording region
  305. for zz = 1: numZones %cycle through recording zones
  306. zoneName = strcat('Zone',num2str(zz)); %get the zone name to access the data structure
  307. startR = find(Zonez==zz,1,'first'); %get the first region in the zone
  308. endR = find(Zonez==zz,1,'last'); %get the last region in the zone
  309. LFGroupz = zeros(NumberOfleaderClassificationGroups,NumberOfleaderClassificationGroups); %Initialize array to save probability of being in a group given the past group
  310. PCGroupz = zeros(NumberOfpkCountClassificationGroups,NumberOfpkCountClassificationGroups); %Initialize array to save probability of being in a group given the past group
  311. UnifGroupz = zeros(NumberOfunifClassificationGroups,NumberOfunifClassificationGroups); %Initialize array to save probability of being in a group given the past group
  312. %row = previous group, column = probability of current group
  313. for rr = max(2,startR):endR %cycle through regions within the zone...
  314. %Get the probability of a current leader/follower classification given the value of the previous classification
  315. for g = 1:NumberOfleaderClassificationGroups %cycle through past group...
  316. g_name = ['G' num2str(g)]; %get the group name
  317. indArr = FindGroups.LeaderFollower.(g_name); %find correlograms classified in the given group
  318. previouslyInGroup = indArr(:,rr-1); %find correlograms belonging to the given group in the previous analysis region
  319. currentGroup = LFGroupAssignments(previouslyInGroup,rr); %find how those correlograms are classified in the current analysis region
  320. for g2 = 1:NumberOfleaderClassificationGroups %for each current group...
  321. LFGroupz(g,g2) = LFGroupz(g,g2)+sum(currentGroup==g2); %add current groups to histogram counts
  322. end %end cycle through current groups
  323. end %end cycle through past group
  324. %Get the probability of a current peak count given the value of the previous peak count
  325. for g = 1:NumberOfpkCountClassificationGroups %cycle through past group...
  326. g_name = ['G' num2str(g)]; %get the group name
  327. indArr = FindGroups.PeakCount.(g_name); %find correlograms classified in the given group
  328. previouslyInGroup = indArr(:,rr-1); %find correlograms belonging to the given group in the previous analysis region
  329. currentGroup = PCGroupAssignments(previouslyInGroup,rr); %find how those correlograms are classified in the current analysis region
  330. for g2 = 1:NumberOfpkCountClassificationGroups %for each current group...
  331. PCGroupz(g,g2) = PCGroupz(g,g2)+sum(currentGroup==g2); %add current groups to histogram counts
  332. end %end cycle through current groups
  333. end %end cycle through past group
  334. %Get the probability of a current uniformity classification given the value of the previous uniformity classification
  335. for g = 1:NumberOfunifClassificationGroups %cycle through past group...
  336. g_name = ['G' num2str(g)]; %get the group name
  337. indArr = FindGroups.Unif.(g_name); %find correlograms classified in the given group
  338. previouslyInGroup = indArr(:,rr-1); %find correlograms belonging to the given group in the previous analysis region
  339. currentGroup = unifGroupAssignments(previouslyInGroup,rr); %find how those correlograms are classified in the current analysis region
  340. for g2 = 1:NumberOfunifClassificationGroups %for each current group...
  341. UnifGroupz(g,g2) = UnifGroupz(g,g2)+sum(currentGroup==g2); %add current groups to histogram counts
  342. end %end cycle through current groups
  343. end %end cycle through past group
  344. end %end cycle through analysis regions within the zone
  345. ZoneHistograms.LeaderFollower.(zoneName) = LFGroupz./sum(LFGroupz,2); %normalize histogram to probabilities and save in the structure so you can plot histograms for each zone
  346. ZoneHistograms.PeakCount.(zoneName) = PCGroupz./sum(PCGroupz,2); %normalize histogram to probabilities and save in the structure so you can plot histograms for each zone
  347. ZoneHistograms.Unif.(zoneName) = UnifGroupz./sum(UnifGroupz,2); %normalize histogram to probabilities and save in the structure so you can plot histograms for each zone
  348. end %end cycle through recording zones
  349. %% Make Plots of Classification Outputs
  350. %Initialize plot markers for ease of plotting
  351. markerNmArr = {'o','*','x','square','diamond','^','v','>','<','pentagram','hexagram','+','.'}; %Make an array to change the plot marker shapes for each category of classified data
  352. markerSzArr = [plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize*0.4 plotProps.markerSize];
  353. %Make sure there are enough marker indicators for all plots to be made
  354. maxClassificationCount = (1+min(plotProps.maxPeakCountBeforeNoise,max(numPeaksArray(:)))); %The highest number of classifications will be peak counts, so make sure length(markerArray) is larger than the max possible number of peak counts
  355. maxClassificationCount = max(length(ProcessedData.RegionStats.groupOrder),maxClassificationCount); %the highest possible number of lines on that plots will be the number of analysis regions
  356. F = maxClassificationCount/length(markerNmArr); %The highest number of classifications will be peak counts, so make sure length(markerArray) is larger than the max possible number of peak counts
  357. if F > 1 %if the marker array is too short to plot all peak classifications
  358. F = ceil(F); %round up so the array will eventually be longer than needed
  359. for i = 1:F %as many times as needed...
  360. markerNmArr = [markerNmArr markerNmArr]; %lengthen the marker name array as many times as needed
  361. markerSzArr = [markerSzArr markerSzArr];
  362. end
  363. end %end check marker specification is long enough
  364. %Plot the fraction of correlogram peaks in each leader/follower classification
  365. cc = pink(NumberOfleaderClassificationGroups+4); %set plot colors
  366. figure()
  367. %Indicate where injuries/treatments occurred
  368. hold on
  369. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury, shade where the injury occurred
  370. for j = 1:InjuryIndicies.NumberOfInjuriesOrTreatments %for all injuries/treatments...
  371. plot([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  372. plot([InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  373. fill([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2 2 -1],[0.6 0.6 0.6],'facealpha',0.2,'LineStyle','none')
  374. if InjuryInds(3,j) ~= 1 %if injury/treatment is mid-recoding
  375. text(InjuryInds(1,j) ,max(fracInProbGroup(:))+.05,InjuryIndicies.InjuryLabels{j},'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  376. else %otherwise injury/treatment is before recording start
  377. text(InjuryInds(1,j) ,max(fracInProbGroup(:))+.05,[InjuryIndicies.InjuryLabels{j} ' Before Recording Start'],'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  378. end
  379. end
  380. end
  381. %Now plot the fraction of correlogram peaks in each classification
  382. h=plot(1:AnalysisRegions.numRegions,fracInProbGroup','.-','LineWidth',plotProps.lineWidth);
  383. hold off
  384. for c = 1:size(h,1)
  385. h(c).Color = cc(c,:);
  386. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  387. end
  388. set(gca,'XTick',1:AnalysisRegions.numRegions)
  389. if isfield(AnalysisRegions,'RegionLabels')
  390. set(gca,'XTickLabel',AnalysisRegions.RegionLabels)
  391. end
  392. xlim([0.5 AnalysisRegions.numRegions+0.5])
  393. xlabel('Recording Region')
  394. ylim([0 1.2*(max(fracInProbGroup(:)))])
  395. ylabel('Fraction of Correlograms with a given Classification')
  396. legend(h,leaderClassificationNames)
  397. set(gca,'FontSize',plotProps.FigureFontSize)
  398. title('Classification of Leader/Follower Nature Through Time')
  399. box on
  400. set(gca,'YTick',0:0.05:1)
  401. ax = gca;
  402. ax.YGrid = 'on';
  403. %Plot the fraction of correlogram peaks in each peak count
  404. cc = pink(NumberOfpkCountClassificationGroups+4); %set plot colors
  405. figure()
  406. %Indicate where injuries/treatments occurred
  407. hold on
  408. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury, shade where the injury occurred
  409. for j = 1:InjuryIndicies.NumberOfInjuriesOrTreatments %for all injuries/treatments...
  410. plot([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  411. plot([InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  412. fill([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2 2 -1],[0.6 0.6 0.6],'facealpha',0.2,'LineStyle','none')
  413. if InjuryInds(3,j) ~= 1 %if injury/treatment is mid-recoding
  414. text(InjuryInds(1,j) ,max(fracInPeakGroup(:))+.05,InjuryIndicies.InjuryLabels{j},'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  415. else %otherwise injury/treatment is before recording start
  416. text(InjuryInds(1,j) ,max(fracInPeakGroup(:))+.05,[InjuryIndicies.InjuryLabels{j} ' Before Recording Start'],'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  417. end
  418. end
  419. end
  420. %Now plot the fraction of correlogram peaks in each classification
  421. h=plot(1:AnalysisRegions.numRegions,fracInPeakGroup','.-','LineWidth',plotProps.lineWidth);
  422. hold off
  423. for c = 1:size(h,1)
  424. h(c).Color = cc(c,:);
  425. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  426. end
  427. set(gca,'XTick',1:AnalysisRegions.numRegions)
  428. if isfield(AnalysisRegions,'RegionLabels')
  429. set(gca,'XTickLabel',AnalysisRegions.RegionLabels)
  430. end
  431. xlim([0.5 AnalysisRegions.numRegions+0.5])
  432. xlabel('Recording Region')
  433. ylim([0 1.2*(max(fracInPeakGroup(:)))])
  434. ylabel('Fraction of Correlograms with a given Peak Count')
  435. legend(h,pkCountNames)
  436. set(gca,'FontSize',plotProps.FigureFontSize)
  437. title('Peak Counts Through Time')
  438. box on
  439. set(gca,'YTick',0:0.1:1)
  440. ax = gca;
  441. ax.YGrid = 'on';
  442. %Plot the fraction of correlogram that are uniform and nonuniform
  443. cc = pink(4); %set plot colors
  444. figure()
  445. %Indicate where injuries/treatments occurred
  446. hold on
  447. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury, shade where the injury occurred
  448. for j = 1:InjuryIndicies.NumberOfInjuriesOrTreatments %for all injuries/treatments...
  449. plot([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  450. plot([InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  451. fill([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2 2 -1],[0.6 0.6 0.6],'facealpha',0.2,'LineStyle','none')
  452. if InjuryInds(3,j) ~= 1 %if injury/treatment is mid-recoding
  453. text(InjuryInds(1,j) ,max(fracInUnifGroup(:))+.05,InjuryIndicies.InjuryLabels{j},'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  454. else %otherwise injury/treatment is before recording start
  455. text(InjuryInds(1,j) ,max(fracInUnifGroup(:))+.05,[InjuryIndicies.InjuryLabels{j} ' Before Recording Start'],'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  456. end
  457. end
  458. end
  459. %Now plot the fraction of correlogram peaks in each classification
  460. h=plot(1:AnalysisRegions.numRegions,fracInUnifGroup','.-','LineWidth',plotProps.lineWidth);
  461. hold off
  462. for c = 1:size(h,1)
  463. h(c).Color = cc(c,:);
  464. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  465. end
  466. set(gca,'XTick',1:AnalysisRegions.numRegions)
  467. if isfield(AnalysisRegions,'RegionLabels')
  468. set(gca,'XTickLabel',AnalysisRegions.RegionLabels)
  469. end
  470. xlim([0.5 AnalysisRegions.numRegions+0.5])
  471. xlabel('Recording Region')
  472. ylim([0 1.1*(max(fracInUnifGroup(:)))])
  473. ylabel('Fraction of Correlograms with a given Uniformity')
  474. legend(h,unifNames)
  475. set(gca,'FontSize',plotProps.FigureFontSize)
  476. title('Correlogram Uniformity Through Time')
  477. box on
  478. set(gca,'YTick',0:0.1:1)
  479. ax = gca;
  480. ax.YGrid = 'on';
  481. %Plot the fraction of correlogram peaks in each EEG classification
  482. cc = pink(NumberOfFreqClassificationGroups+4); %set plot colors
  483. figure()
  484. %Indicate where injuries/treatments occurred
  485. hold on
  486. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury, shade where the injury occurred
  487. for j = 1:InjuryIndicies.NumberOfInjuriesOrTreatments %for all injuries/treatments...
  488. plot([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  489. plot([InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2],'--k','LineWidth',plotProps.lineWidth/2)
  490. fill([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[-1 2 2 -1],[0.6 0.6 0.6],'facealpha',0.2,'LineStyle','none')
  491. if InjuryInds(3,j) ~= 1 %if injury/treatment is mid-recoding
  492. text(InjuryInds(1,j) ,max(fracInFreqGroup(:))+.05,InjuryIndicies.InjuryLabels{j},'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  493. else %otherwise injury/treatment is before recording start
  494. text(InjuryInds(1,j) ,max(fracInFreqGroup(:))+.05,[InjuryIndicies.InjuryLabels{j} ' Before Recording Start'],'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  495. end
  496. end
  497. end
  498. %Now plot the fraction of correlogram peaks in each classification
  499. h=plot(1:AnalysisRegions.numRegions,fracInFreqGroup','.-','LineWidth',plotProps.lineWidth);
  500. hold off
  501. for c = 1:size(h,1)
  502. h(c).Color = cc(c,:);
  503. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  504. end
  505. set(gca,'XTick',1:AnalysisRegions.numRegions)
  506. if isfield(AnalysisRegions,'RegionLabels')
  507. set(gca,'XTickLabel',AnalysisRegions.RegionLabels)
  508. end
  509. xlim([0.5 AnalysisRegions.numRegions+0.5])
  510. xlabel('Recording Region')
  511. ylim([0 1.2*(max(fracInFreqGroup(:)))])
  512. if plotProps.classifyPeakTimesAsFrequencies == 1
  513. ylabel('Fraction of Correlogram Peaks in Each Frequency Band')
  514. title('Peak Frequency Classification Through Time')
  515. else
  516. ylabel('Fraction of Correlogram Peaks in Each Time Range')
  517. title('Peak Location Classification Through Time')
  518. end
  519. legend(h,freqClassificationNames)
  520. set(gca,'FontSize',plotProps.FigureFontSize)
  521. box on
  522. set(gca,'YTick',0:0.1:1)
  523. ax = gca;
  524. ax.YGrid = 'on';
  525. %Plot the average plus/minus standard deviation of the frequency of each band
  526. errorbarx = zeros(AnalysisRegions.numRegions,NumberOfFreqClassificationGroups); %set x array to give errorbar plots the correct x coordinate
  527. for g = 1:NumberOfFreqClassificationGroups
  528. errorbarx(:,g)=1:AnalysisRegions.numRegions;
  529. end
  530. %%{
  531. %error bars = range of the data
  532. maxValy = maxFreqInFreqGroup-meanFreqInFreqGroup; maxVal = max(maxValy(:)); %find the maximum frequency
  533. minValy = meanFreqInFreqGroup-minFreqInFreqGroup; minVal = min(min(minValy(:)),0.9); %find the minimum frequency
  534. %}
  535. %%{
  536. %error bars = standard deviation of the data
  537. maxValy = meanFreqInFreqGroup+sdFreqInFreqGroup; maxVal = max(maxValy(:)); %find the maximum frequency
  538. minValy = meanFreqInFreqGroup-sdFreqInFreqGroup; minVal = min(min(minValy(:)),0.9); %find the minimum frequency
  539. %}
  540. %{
  541. %error bars = standard error of the data
  542. maxValy = meanFreqInFreqGroup+seFreqInFreqGroup; maxVal = max(maxValy(:)); %find the maximum frequency
  543. minValy = meanFreqInFreqGroup-seFreqInFreqGroup; minVal = min(min(minValy(:)),0.9); %find the minimum frequency
  544. %}
  545. %get y-axis limits
  546. if plotProps.classifyPeakTimesAsFrequencies == 1
  547. %Get powers of 10 to set y limits for the frequency plots
  548. vS = num2str(minVal); b = strfind(vS,'0'); %find zeros in the minimum frequency
  549. if length(b)>1
  550. lowestPower = min(1+strfind(vS,'.'), b(2))-strfind(vS,'.'); %get the position after decimal where the minimum value starts (i.e. 1 = 0.1, 2 = 0.01, 3 = 0.001, 4 = 0.0001, etc...)
  551. minVal = 10.^-lowestPower;
  552. else %otherwise, mean - error went negative
  553. lowestPower = 1;
  554. minVal = 10.^-lowestPower;
  555. end
  556. highestPower = ceil(log10(maxVal)); %get the highest power to set upper y limit
  557. else %otherwise classifying by peak times, not frequency
  558. lowestPower= -min(endpowr);
  559. minVal = 0;
  560. highestPower = 0.1+max([stpowr endpowr]);
  561. end
  562. if plotProps.plotPeakLocationClassificationMedian == 1
  563. labelStr = 'Median';
  564. else
  565. labelStr = 'Mean';
  566. end
  567. figure()
  568. %Indicate where injuries/treatments occurred
  569. hold on
  570. if InjuryIndicies.NumberOfInjuriesOrTreatments > 0 %if there was an injury, shade where the injury occurred
  571. for j = 1:InjuryIndicies.NumberOfInjuriesOrTreatments %for all injuries/treatments...
  572. plot([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j)],[10.^(-lowestPower-1) 10.^highestPower],'--k','LineWidth',plotProps.lineWidth/2)
  573. plot([InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[10.^(-lowestPower-1) 10.^highestPower],'--k','LineWidth',plotProps.lineWidth/2)
  574. fill([InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)-InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j) InjuryInds(1,j)+InjuryInds(2,j)],[10.^(-lowestPower-1) 10.^highestPower 10.^highestPower 10.^(-lowestPower-1)],[0.6 0.6 0.6],'facealpha',0.2,'LineStyle','none')
  575. if InjuryInds(3,j) ~= 1 %if injury/treatment is mid-recoding
  576. text(InjuryInds(1,j) ,min(maxVal*1.5,9.5.^highestPower),InjuryIndicies.InjuryLabels{j},'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  577. else %otherwise injury/treatment is before recording start
  578. text(InjuryInds(1,j) ,min(maxVal*1.5,9.5.^highestPower),[InjuryIndicies.InjuryLabels{j} ' Before Recording Start'],'FontSize',plotProps.FigureFontSize*0.8,'HorizontalAlignment', 'center')
  579. end
  580. end
  581. end
  582. %Now plot mean plus/minus standard deviation in the frequencies of each group
  583. %h = errorbar(errorbarx,meanFreqInFreqGroup',minValy',maxValy','LineWidth',floor(plotProps.lineWidth*3/4));
  584. if plotProps.plotPeakLocationClassificationMedian == 1
  585. h = plot(errorbarx,medianFreqInFreqGroup','.-','LineWidth',floor(plotProps.lineWidth*3/4));
  586. else
  587. h = plot(errorbarx,meanFreqInFreqGroup','.-','LineWidth',floor(plotProps.lineWidth*3/4));
  588. end
  589. hold off
  590. %for c = 1:size(h,2)
  591. for c = 1:size(h,1)
  592. h(c).Color = cc(c,:);
  593. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  594. end
  595. set(gca,'XTick',1:AnalysisRegions.numRegions)
  596. if isfield(AnalysisRegions,'RegionLabels')
  597. set(gca,'XTickLabel',AnalysisRegions.RegionLabels)
  598. end
  599. xlim([0.5 AnalysisRegions.numRegions+0.5])
  600. xlabel('Recording Region')
  601. ylim([minVal 10.^highestPower])
  602. if plotProps.classifyPeakTimesAsFrequencies == 1
  603. ylabel([labelStr ' Frequency of Peaks in Each Band (Hz)'])
  604. title('Peak Frequencies Through Time')
  605. else
  606. ylabel([labelStr ' Peak Times in Each Group (s)'])
  607. title('Peak Locations Through Time')
  608. end
  609. legend(h,freqClassificationNames)
  610. set(gca,'FontSize',plotProps.FigureFontSize)
  611. box on
  612. set(gca,'YTick',10.^[-lowestPower:highestPower])
  613. ax = gca;
  614. ax.YGrid = 'on';
  615. set(gca,'YScale','log')
  616. %% Plot Classification Changes
  617. %Plot group switching dynamics in different recording zones
  618. cc = pink(numZones+2); %set plot colors
  619. figure()
  620. for g = 1:NumberOfleaderClassificationGroups %for each group...
  621. q = zeros(numZones,length(ZoneHistograms.LeaderFollower.Zone1));
  622. for zz = 1:numZones %cycle through zones...
  623. zoneName = strcat('Zone',num2str(zz)); %get the zone name to access the data structure
  624. histArray = ZoneHistograms.LeaderFollower.(zoneName); %for the zone, get the probabilities of being in current group, given past group
  625. q(zz,:) = ZoneHistograms.LeaderFollower.(zoneName)(g,:);
  626. end %end cycle through zones
  627. q = q';
  628. subplot(1,NumberOfleaderClassificationGroups,g)
  629. hold on
  630. h=plot(1:NumberOfleaderClassificationGroups, q,'-','MarkerSize',plotProps.markerSize,'LineWidth',plotProps.lineWidth);
  631. hold off
  632. for c = 1:size(h,1)
  633. h(c).Color = cc(c,:);
  634. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  635. end
  636. box on
  637. grid on
  638. title(['Previously Classified as ' leaderClassificationNames{g}])
  639. ylim([0 1])
  640. xlim([0 NumberOfleaderClassificationGroups+1])
  641. set(gca,'YTick',0:0.1:1)
  642. legend(groupOrder);
  643. ylabel('Probability of Current Classification')
  644. set(gca,'XTick',1:NumberOfleaderClassificationGroups,'XTickLabel',leaderClassificationNames)
  645. xlabel('Current Classification')
  646. set(gca,'FontSize',plotProps.FigureFontSize*0.7)
  647. end
  648. %Plot peak count switching dynamics in different recording zones
  649. c = min(10,NumberOfpkCountClassificationGroups);
  650. r = ceil(NumberOfpkCountClassificationGroups/c);
  651. figure()
  652. t=tiledlayout(r,c,'Padding','none','TileSpacing','compact','Padding','compact');
  653. for g = 1:NumberOfpkCountClassificationGroups %for each group...
  654. q = zeros(numZones,length(ZoneHistograms.PeakCount.Zone1));
  655. for zz = 1:numZones %cycle through zones...
  656. zoneName = strcat('Zone',num2str(zz)); %get the zone name to access the data structure
  657. histArray = ZoneHistograms.PeakCount.(zoneName); %for the zone, get the probabilities of being in current group, given past group
  658. q(zz,:) = ZoneHistograms.PeakCount.(zoneName)(g,:);
  659. end %end cycle through zones
  660. q = q';
  661. nexttile
  662. hold on
  663. h=plot(1:NumberOfpkCountClassificationGroups, q,'-','LineWidth',plotProps.lineWidth);
  664. hold off
  665. for c = 1:size(h,1)
  666. h(c).Color = cc(c,:);
  667. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  668. end
  669. box on
  670. grid on
  671. title(['Previous Peak Count = ' pkCountNames{g}])
  672. ylim([0 1])
  673. xlim([0 NumberOfpkCountClassificationGroups+1])
  674. set(gca,'YTick',0:0.1:1)
  675. legend(groupOrder);
  676. set(gca,'XTick',1:NumberOfpkCountClassificationGroups,'XTickLabel',pkCountNames)
  677. set(gca,'FontSize',plotProps.FigureFontSize*0.7)
  678. end
  679. ylabel(t,'Probability of Current Peak Count','FontSize',plotProps.FigureFontSize)
  680. xlabel(t,'Current Peak Count','FontSize',plotProps.FigureFontSize)
  681. %Plot uniformity switching dynamics in different recording zones
  682. c = min(10,NumberOfunifClassificationGroups);
  683. r = ceil(NumberOfunifClassificationGroups/c);
  684. figure()
  685. t=tiledlayout(r,c,'Padding','none','TileSpacing','compact','Padding','compact');
  686. for g = 1:NumberOfunifClassificationGroups %for each group...
  687. q = zeros(numZones,length(ZoneHistograms.Unif.Zone1));
  688. for zz = 1:numZones %cycle through zones...
  689. zoneName = strcat('Zone',num2str(zz)); %get the zone name to access the data structure
  690. histArray = ZoneHistograms.Unif.(zoneName); %for the zone, get the probabilities of being in current group, given past group
  691. q(zz,:) = ZoneHistograms.Unif.(zoneName)(g,:);
  692. end %end cycle through zones
  693. q = q';
  694. nexttile
  695. hold on
  696. h=plot(1:NumberOfunifClassificationGroups, q,'-','LineWidth',plotProps.lineWidth);
  697. hold off
  698. for c = 1:size(h,1)
  699. h(c).Color = cc(c,:);
  700. h(c).Marker = markerNmArr{c}; h(c).MarkerSize = markerSzArr(c);
  701. end
  702. box on
  703. grid on
  704. title(['Previously ' unifNames{g}])
  705. ylim([0 1])
  706. xlim([0 NumberOfunifClassificationGroups+1])
  707. set(gca,'YTick',0:0.1:1)
  708. legend(groupOrder);
  709. set(gca,'XTick',1:NumberOfunifClassificationGroups,'XTickLabel',unifNames)
  710. set(gca,'FontSize',plotProps.FigureFontSize*0.7)
  711. end
  712. ylabel(t,'Probability of Current Uniformity','FontSize',plotProps.FigureFontSize)
  713. xlabel(t,'Current Uniformity','FontSize',plotProps.FigureFontSize)
  714. %% Plot a summary of all possible correlogram classifications, and the percent of correlograms that fall into each category
  715. totalCorrelogramCount = size(LFGroupAssignments,1)-sum(isnan(LFGroupAssignments)); %get total number of correlograms
  716. UnifMat = zeros(NumberOfpkCountClassificationGroups,NumberOfleaderClassificationGroups,numZones); %initialize array to store classification combos of uniform correlograms
  717. NonUnifMat = zeros(NumberOfpkCountClassificationGroups,NumberOfleaderClassificationGroups,numZones); %initialize array to store classification combos of nonuniform correlograms
  718. for rr = 1:numZones %for each recording region or zone...
  719. rrInds = Zonez == rr;
  720. for u = 1:NumberOfunifClassificationGroups %for each uniformity classification...
  721. nm = strcat('G',num2str(u)); %get the uniformity group name
  722. UIdx=FindGroups.Unif.(nm)(:,rrInds); %find correlograms classified with the given value (nonuniform or uniform)
  723. for p = 1:NumberOfpkCountClassificationGroups %cycle through peak counts
  724. nm2 = strcat('G',num2str(p)); %get the peak count group name
  725. PIdx = FindGroups.PeakCount.(nm2)(:,rrInds); %find correlograms with the given peak count
  726. for l = 1:NumberOfleaderClassificationGroups %cycle through leader/follower groupings
  727. nm3 = strcat('G',num2str(l)); %get the leader/follower group name
  728. LIdx = FindGroups.LeaderFollower.(nm3)(:,rrInds); %find correlograms with the given leader/follower classification
  729. if u == 1 %check in which uniformity matrix to save the entry
  730. NonUnifMat(p,l,rr) = sum(sum(UIdx&PIdx&LIdx))./sum(totalCorrelogramCount(rrInds));
  731. else %otherwise uniform matrix
  732. UnifMat(p,l,rr) = sum(sum(UIdx&PIdx&LIdx))./sum(totalCorrelogramCount(rrInds));
  733. end %end save the fraction of correlograms with a given classification combo in the matrix
  734. end %end cycle through leader/follower groupings
  735. end %end cycle through peak counts
  736. end %end cycle through uniformity classifications
  737. end %end cycle through zones
  738. %Get x and y coordinates for the plot (these are peak counts and leader/follower classifications, uniformity is plotted as different markers)
  739. x = pkCountGroupBoundaries;
  740. y = 1:NumberOfleaderClassificationGroups;
  741. colormapLength = 256;
  742. cc = [1 1 1; jet(colormapLength)]; %get colormap to shade correlogram percentages
  743. xposshift = 0;%0.1; %set a shift factor for the x position so uniform and uniform points are not plotted on top of eachother
  744. yposshift = 0.07; %set a shift factor for the y position so uniform and uniform points are not plotted on top of eachother
  745. for rr = 1:numZones %for each recording zone
  746. figure()
  747. hold on
  748. for xx = 1:length(x) %for each peak count...
  749. for yy = 1:length(y) %for each leader/follower class...
  750. %Plot uniform correlograms
  751. cmapIdx2 = max(1,1+ceil(colormapLength.*UnifMat(xx,yy,rr))); %shade the point according to % of correlograms with the given classification combo
  752. plot(x(xx)+xposshift,y(yy)+yposshift,'^','Color',cc(cmapIdx2,:),'MarkerSize',20,'MarkerFaceColor',cc(cmapIdx2,:),'MarkerEdgeColor',[0 0 0])
  753. text(x(xx)+xposshift+0.1,y(yy)+yposshift+0.1,[num2str(100.*UnifMat(xx,yy,rr),'%.1f') '%']) %display the % of correlograms with the given classification combo
  754. %Plot nonuniform correlograms
  755. cmapIdx = max(1,1+ceil(colormapLength.*NonUnifMat(xx,yy,rr))); %shade according to % of correlograms with the given classification combo
  756. plot(x(xx)-xposshift,y(yy)-yposshift,'v','MarkerSize',20,'MarkerFaceColor',cc(cmapIdx,:),'MarkerEdgeColor',[0 0 0])
  757. text(x(xx)-xposshift+0.1,y(yy)-yposshift-0.1,[num2str(100.*NonUnifMat(xx,yy,rr),'%.1f') '%']) %display the % of correlograms with the given classification combo
  758. end %end cycle through leader/follower classes
  759. end %end cycle through peak counts
  760. %Plot empty points for the legend
  761. h1=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength)),:),'MarkerEdgeColor',[0 0 0]);
  762. h2=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.9)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.9)),:),'MarkerEdgeColor',[0 0 0]);
  763. h3=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.8)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.8)),:),'MarkerEdgeColor',[0 0 0]);
  764. h4=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.7)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.7)),:),'MarkerEdgeColor',[0 0 0]);
  765. h5=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.6)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.6)),:),'MarkerEdgeColor',[0 0 0]);
  766. h6=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.5)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.5)),:),'MarkerEdgeColor',[0 0 0]);
  767. h7=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.4)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.4)),:),'MarkerEdgeColor',[0 0 0]);
  768. h8=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.3)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.3)),:),'MarkerEdgeColor',[0 0 0]);
  769. h9=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.2)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.2)),:),'MarkerEdgeColor',[0 0 0]);
  770. h10=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0.1)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0.1)),:),'MarkerEdgeColor',[0 0 0]);
  771. h11=plot(NaN,NaN,'s','Color',cc(max(1,round(colormapLength*0)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0)),:),'MarkerEdgeColor',[0 0 0]);
  772. hnu = plot(NaN,NaN,'v','Color',cc(max(1,round(colormapLength*0)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0)),:),'MarkerEdgeColor',[0 0 0]);
  773. hu = plot(NaN,NaN,'^','Color',cc(max(1,round(colormapLength*0)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0)),:),'MarkerEdgeColor',[0 0 0]);
  774. hblank = plot(NaN,NaN,'^','Color',cc(max(1,round(colormapLength*0)),:),'MarkerSize',20,'MarkerFaceColor',cc(max(1,round(colormapLength*0)),:),'MarkerEdgeColor',[1 1 1]);
  775. hold off
  776. %legend([hu,hnu,hblank, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11], {'Uniform Correlograms';'Nonuniform Correlograms';'Color = Percent of all Correlograms:'; '100%';'90%';'80%';'70%';'60%';'50%';'40%';'30%';'20%';'10%';'0%'},'Location','EastOutside')
  777. legend([hu,hnu,h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11], {'Uniform Correlograms';'Nonuniform Correlograms';'100% Percent of all Correlograms';'90% Percent of all Correlograms';'80% Percent of all Correlograms';'70% Percent of all Correlograms';'60% Percent of all Correlograms';'50% Percent of all Correlograms';'40% Percent of all Correlograms';'30% Percent of all Correlograms';'20% Percent of all Correlograms';'10% Percent of all Correlograms';'0% Percent of all Correlograms'},'Location','EastOutside')
  778. box on
  779. grid on
  780. xlim([min(x)-10*max(xposshift,yposshift) max(x)+10*max(xposshift,yposshift)])
  781. ylim([min(y)-10*max(xposshift,yposshift) max(y)+10*max(xposshift,yposshift)])
  782. set(gca,'XTick',x,'XTickLabel',pkCountNames)
  783. xlabel('Number of Correlogram Peaks')
  784. set(gca,'YTick',y,'YTickLabel',leaderClassificationNames)
  785. ylabel('Leader/Follower Strength Classification')
  786. title(groupOrder{rr})
  787. set(gca,'FontSize',plotProps.FigureFontSize)
  788. end %end cycle through recording zones
  789. end

summarizeCorrelograms.m at commit 1ce9141, under MIT · at the source

Overview

  1. Center for Paralysis Research, Purdue University, West Lafayette, IN 47907 USA
  2. Department of Basic Medical Sciences, School of Veterinary Medicine, Purdue University, West Lafayette, IN 47907 USA
  3. Weldon School of Biomedical Engineering, Purdue University, West Lafayette, IN 47907 USA
  4. Indiana University School of Medicine, 340 West 10 StreetSuite 6200, Fairbanks HallIndianapolis, IN 46202-3082 USA
Journal: Neuroinformatics, volume 24, issue 2, article 24
Dates: received 3 September 2025; accepted 26 January 2026; published online 27 April 2026; in print 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1007/s12021-026-09770-9 · PMID 42036490 · PMCID PMC13111530 · OpenAlex W7155741402
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: traumatic brain injury (population), methods / tools (subfield)
Methods: Preprocessing, Connectivity, Statistics, Single-unit activity, calcium imaging
Keywords: Raster, Correlogram, Bicuculline, Alkalosis, Injury, Software
MeSH: Action Potentials*, Brain Injuries, Traumatic*, Neurons*, Algorithms, Animals, Bicuculline, Microelectrodes, Signal Processing, Computer-Assisted (* major topic)
Topic: Neuroscience and Neural Engineering (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 89 references in the paper

Abstract

Changes in neuronal network dynamics in response to different treatments or conditions underly brain function and pathology. A multitude of tools, including electroencephalography, voltage or calcium imaging, and microelectrode array (MEA) recordings, exist to record signals from neuronal firing at different length scales. Correlograms are a standard analysis tool to study the relationship between a pair of recorded neuronal signals. Correlogram shape can provide information about signal independence, firing pattern, and firing order. However, such analysis is performed manually and qualitatively, limiting the amount of information gained. To overcome this limitation, a MATLAB algorithm was developed to automate correlogram shape quantification by calculating correlogram uniformity, peak count and location, and area left of zero, which respectively quantify signal independence/dependence, firing pattern, and firing order. Algorithm outputs were validated using three different MEA recordings during which cells were exposed to bicuculline methiodide, pH shock, or impact injury. Algorithm outputs described signaling changes in all three recordings, bridged changes in individual signal pairings to changes in the entire signal population, and agreed with literature studies. Therefore, this algorithm serves as a useful means of automatically quantifying changes in signal dependence, firing pattern, and firing order across time within a single recording, and across different recordings. These features are also common to all recording techniques, and therefore can be compared across different types of recordings. Therefore, the MATLAB algorithm described in this article can help provide insight into how neural network dynamics are altered by different drugs or conditions.

Supplementary Information: The online version contains supplementary material available at 10.1007/s12021-026-09770-9.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 12 matches between paragraphs and lines of code.

ceadm/Correlogram-Uniformty-Peak-Count-Area-Left-of-Zero

License: MIT
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 1ce9141968e05c8cf5b48fd1a04ce067c1493c59, 10 June 2026
Languages: MATLAB (18), C/C++ (1), C (1)
Size: 24 files, 20 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
22 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 20 scripts, each with its path and the digest of its content;
  • 12 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

No dataset and no data link were found in the paper.

Data Availability

The MATLAB script is available on GitHub (https://github.com/ceadm/Correlogram-Uniformty-Peak-Count-Area-Left-of-Zero.git) as well as in the supplementary material of this work. Recording files are also provided with the code in the supplementary material of this work.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 8 authors, 6 keywords, 8 MeSH terms, 80 references.

Cite

This paper

Adam, C. E., Mufti, S. J., Martinez, J., Rogers, E. A., Dalolio, M., Krishnan, N., Beauclair, T., & Shi, R. (2026). Quantifying Correlogram Shape to Analyze Neuronal Firing Dynamics Recorded in TBI-on-a-Chip. Neuroinformatics, 24(2), 24. https://doi.org/10.1007/s12021-026-09770-9

BibTeX

@article{adam2026quantifying,
author = {Adam, Casey Erin and Mufti, Shatha J and Martinez, Jhon and Rogers, Edmond A and Dalolio, Martina and Krishnan, Nikita and Beauclair, Timothy and Shi, Riyi},
title = {{Quantifying Correlogram Shape to Analyze Neuronal Firing Dynamics Recorded in TBI-on-a-Chip}},
journal = {Neuroinformatics},
year = {2026},
month = apr,
volume = {24},
number = {2},
pages = {24},
publisher = {Springer Science+Business Media},
issn = {1539-2791},
doi = {10.1007/s12021-026-09770-9},
url = {https://doi.org/10.1007/s12021-026-09770-9},
pmid = {42036490},
pmcid = {PMC13111530}
}

RIS

TY - JOUR
AU - Adam, Casey Erin
AU - Mufti, Shatha J
AU - Martinez, Jhon
AU - Rogers, Edmond A
AU - Dalolio, Martina
AU - Krishnan, Nikita
AU - Beauclair, Timothy
AU - Shi, Riyi
TI - Quantifying Correlogram Shape to Analyze Neuronal Firing Dynamics Recorded in TBI-on-a-Chip
T2 - Neuroinformatics
J2 - Neuroinformatics
PY - 2026
DA - 2026/04/27
VL - 24
IS - 2
SP - 24
SN - 1539-2791
PB - Springer Science+Business Media
DO - 10.1007/s12021-026-09770-9
UR - https://doi.org/10.1007/s12021-026-09770-9
LA - en
ER -

CSL-JSON

{
"id": "10.1007/s12021-026-09770-9",
"type": "article-journal",
"title": "Quantifying Correlogram Shape to Analyze Neuronal Firing Dynamics Recorded in TBI-on-a-Chip",
"container-title": "Neuroinformatics",
"author": [
{
"family": "Adam",
"given": "Casey Erin"
},
{
"family": "Mufti",
"given": "Shatha J"
},
{
"family": "Martinez",
"given": "Jhon"
},
{
"family": "Rogers",
"given": "Edmond A"
},
{
"family": "Dalolio",
"given": "Martina"
},
{
"family": "Krishnan",
"given": "Nikita"
},
{
"family": "Beauclair",
"given": "Timothy"
},
{
"family": "Shi",
"given": "Riyi"
}
],
"container-title-short": "Neuroinformatics",
"volume": "24",
"issue": "2",
"page": "24",
"DOI": "10.1007/s12021-026-09770-9",
"PMID": "42036490",
"PMCID": "PMC13111530",
"ISSN": "1539-2791",
"publisher": "Springer Science+Business Media",
"URL": "https://doi.org/10.1007/s12021-026-09770-9",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
27
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1080/26941899.2026.2619222
Neurodatascience: Past, Present, and Future.
Journal: Data science in science
In common: 4 references
[2] doi:10.1093/bioinformatics/btag570 [code]
CASCADE: criticality avalanche spike cross-platform analysis detection engine, a multi-manufacturer MEA bash analysis pipeline.
Journal: Bioinformatics (Oxford, England)
In common: methods / tools, 3 references
[3] doi:10.1371/journal.pcbi.1014615 [code]
Toward reliable machine learning models for neural circuit inference: A diagnostic study of CNNs on spike trains.
Journal: PLoS computational biology
In common: 3 references
[4] doi:10.1016/j.bpr.2026.100278
Information flow in cultured neuronal networks by transfer entropy.
Journal: Biophysical reports
In common: 3 references
[5] doi:10.1002/advs.77857 [code]
Brain Network Dynamics of Local and Global Predictive Processing in Aging.
Journal: Advanced science (Weinheim, Baden-Wurttemberg, Germany)
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox
[6] doi:10.1038/s41467-026-76581-6 [code]
Thalamocortical bursts encode reward contingencies and drive associative learning.
Journal: Nature communications
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox
[7] doi:10.1002/glia.70181 [code]
Female Mice Show Stronger Time-of-Day Modulation of Astrocytic Ca&lt;sup&gt;2+&lt;/sup&gt; Activity in the Sleep-Regulatory Ventrolateral Preoptic Nucleus.
Journal: Glia
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox
[8] doi:10.1038/s41467-026-75492-w [code]
Place and behavioral modulation of hippocampal neurons during immobility.
Journal: Nature communications
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox
[9] doi:10.1162/netn.a.554 [code]
The turbulent brain: Modeling vortex interactions for understanding human cognition.
Journal: Network neuroscience (Cambridge, Mass.)
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox
[10] doi:10.1038/s41467-026-75490-y [code]
Topographically organized dorsal raphe activity modulates forebrain sensory-motor representations and contributes to defensive behaviors.
Journal: Nature communications
In common: Violinplot-Matlab, Signal Processing Toolbox, Statistics and Machine Learning Toolbox

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.