Skip to content

Commit 6385b0f

Browse files
committed
final clean
1 parent 482abca commit 6385b0f

File tree

1 file changed

+0
-255
lines changed

1 file changed

+0
-255
lines changed

neo/rawio/neuralynxrawio/ncssections.py

Lines changed: 0 additions & 255 deletions
Original file line numberDiff line numberDiff line change
@@ -170,261 +170,6 @@ def calc_sample_time(sampFr, startTime, posn):
170170
"""
171171
return round(startTime + NcsSectionsFactory.get_micros_per_samp_for_freq(sampFr) * posn)
172172

173-
@staticmethod
174-
def _parseGivenActualFrequency(ncsMemMap, ncsSects, chanNum, reqFreq, blkOnePredTime):
175-
"""
176-
Parse sections in memory mapped file when microsPerSampUsed and sampFreqUsed are known,
177-
filling in an NcsSections object.
178-
179-
Parameters
180-
----------
181-
ncsMemMap:
182-
memmap of Ncs file
183-
ncsSections:
184-
NcsSections with actual sampFreqUsed correct, first NcsSection with proper startSect
185-
and startTime already added.
186-
chanNum:
187-
channel number that should be present in all records
188-
reqFreq:
189-
rounded frequency that all records should contain
190-
blkOnePredTime:
191-
predicted starting time of second record in block
192-
193-
Returns
194-
-------
195-
NcsSections object with block locations marked
196-
"""
197-
198-
# New code numpy vector based (speedup X50)
199-
delta = (ncsMemMap["timestamp"][1:] - ncsMemMap["timestamp"][:-1]).astype(np.int64)
200-
delta_prediction = ((ncsMemMap["nb_valid"][:-1] / ncsSects.sampFreqUsed) * 1e6).astype(np.int64)
201-
gap_inds = np.flatnonzero((delta - delta_prediction) != 0)
202-
gap_inds += 1
203-
sections_limits = [ 0 ] + gap_inds.tolist() + [len(ncsMemMap)]
204-
205-
for i in range(len(gap_inds) + 1):
206-
start = sections_limits[i]
207-
stop = sections_limits[i + 1]
208-
ncsSects.sects.append(
209-
NcsSection(
210-
startRec=start,
211-
startTime=ncsMemMap["timestamp"][start],
212-
endRec=stop-1,
213-
endTime=ncsMemMap["timestamp"][stop-1] + np.uint64(ncsMemMap["nb_valid"][stop-1] / ncsSects.sampFreqUsed * 1e6),
214-
n_samples=np.sum(ncsMemMap["nb_valid"][start:stop])
215-
)
216-
)
217-
218-
return ncsSects
219-
220-
@staticmethod
221-
def _buildGivenActualFrequency(ncsMemMap, actualSampFreq, reqFreq):
222-
"""
223-
Build NcsSections object for file given actual sampling frequency.
224-
225-
Requires that frequency in each record agrees with requested frequency. This is
226-
normally obtained by rounding the header frequency; however, this value may be different
227-
from the rounded actual frequency used in the recording, since the underlying
228-
requirement in older Ncs files was that the number of microseconds per sample in the
229-
records is the inverse of the sampling frequency stated in the header truncated to
230-
whole microseconds.
231-
232-
Parameters
233-
----------
234-
ncsMemMap:
235-
memmap of Ncs file
236-
actualSampFreq:
237-
actual sampling frequency used
238-
reqFreq:
239-
frequency to require in records
240-
241-
Returns
242-
-------
243-
NcsSections object
244-
"""
245-
# check frequency in first record
246-
if ncsMemMap["sample_rate"][0] != reqFreq:
247-
raise IOError("Sampling frequency in first record doesn't agree with header.")
248-
chanNum = ncsMemMap["channel_id"][0]
249-
250-
ncsSects = NcsSections()
251-
ncsSects.sampFreqUsed = actualSampFreq
252-
ncsSects.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq(actualSampFreq)
253-
254-
# check if file is one block of records, which is often the case, and avoid full parse
255-
lastBlkI = ncsMemMap.shape[0] - 1
256-
ts0 = ncsMemMap["timestamp"][0]
257-
nb0 = ncsMemMap["nb_valid"][0]
258-
predLastBlockStartTime = NcsSectionsFactory.calc_sample_time(
259-
actualSampFreq, ts0, NcsSection._RECORD_SIZE * lastBlkI
260-
)
261-
lts = ncsMemMap["timestamp"][lastBlkI]
262-
lnb = ncsMemMap["nb_valid"][lastBlkI]
263-
if (
264-
ncsMemMap["channel_id"][lastBlkI] == chanNum
265-
and ncsMemMap["sample_rate"][lastBlkI] == reqFreq
266-
and lts == predLastBlockStartTime
267-
):
268-
lastBlkEndTime = NcsSectionsFactory.calc_sample_time(actualSampFreq, lts, lnb)
269-
n_samples = NcsSection._RECORD_SIZE * lastBlkI
270-
curBlock = NcsSection(0, ts0, lastBlkI, lastBlkEndTime, n_samples)
271-
272-
ncsSects.sects.append(curBlock)
273-
return ncsSects
274-
275-
276-
else:
277-
# otherwise need to scan looking for data gaps
278-
blkOnePredTime = NcsSectionsFactory.calc_sample_time(actualSampFreq, ts0, nb0)
279-
# curBlock = NcsSection(0, ts0, -1, -1, -1)
280-
# ncsSects.sects.append(curBlock)
281-
ncsSects = NcsSectionsFactory._parseGivenActualFrequency(ncsMemMap, ncsSects, chanNum, reqFreq, blkOnePredTime)
282-
return ncsSects
283-
284-
@staticmethod
285-
def _parseForMaxGap(ncsMemMap, ncsSects, maxGapLen):
286-
"""
287-
Parse blocks of records from file, allowing a maximum gap in timestamps between records
288-
in sections. Estimates frequency being used based on timestamps.
289-
290-
Parameters
291-
----------
292-
ncsMemMap:
293-
memmap of Ncs file
294-
ncsSects:
295-
NcsSections object with sampFreqUsed set to nominal frequency to use in computing time
296-
for samples (Hz)
297-
maxGapLen:
298-
maximum difference within a block between predicted time of start of record and
299-
recorded time
300-
301-
Returns
302-
-------
303-
NcsSections object with sampFreqUsed and microsPerSamp set based on estimate from
304-
largest block
305-
"""
306-
307-
chanNum = ncsMemMap["channel_id"][0]
308-
recFreq = ncsMemMap["sample_rate"][0]
309-
310-
# check for consistent channel_ids and sampling rates
311-
ncsMemMap["channel_id"]
312-
if not (ncsMemMap["channel_id"] == chanNum).all():
313-
raise IOError("Channel number changed in records within file")
314-
315-
if not all(ncsMemMap["sample_rate"] == recFreq):
316-
raise IOError("Sampling frequency changed in records within file")
317-
318-
# find most frequent number of samples
319-
exp_nb_valid = np.argmax(np.bincount(ncsMemMap["nb_valid"]))
320-
# detect records with incomplete number of samples
321-
gap_rec_ids = list(np.where(ncsMemMap["nb_valid"] != exp_nb_valid)[0])
322-
323-
rec_duration = 1e6 / ncsSects.sampFreqUsed * ncsMemMap["nb_valid"]
324-
pred_times = np.rint(ncsMemMap["timestamp"] + rec_duration).astype(np.int64)
325-
max_pred_times = pred_times + maxGapLen
326-
# data records that start later than the predicted time (including the
327-
# maximal accepted gap length) are considered delayed and a gap is
328-
# registered.
329-
delayed_recs = list(np.where(max_pred_times[:-1] < ncsMemMap["timestamp"][1:])[0])
330-
gap_rec_ids.extend(delayed_recs)
331-
332-
# cleaning extracted gap ids
333-
# last record can not be the beginning of a gap
334-
last_rec_id = len(ncsMemMap["timestamp"]) - 1
335-
if last_rec_id in gap_rec_ids:
336-
gap_rec_ids.remove(last_rec_id)
337-
338-
# gap ids can only be listed once
339-
gap_rec_ids = sorted(set(gap_rec_ids))
340-
341-
# create recording segments from identified gaps
342-
ncsSects.sects.append(NcsSection(0, ncsMemMap["timestamp"][0], -1, -1, -1))
343-
for gap_rec_id in gap_rec_ids:
344-
curr_sec = ncsSects.sects[-1]
345-
curr_sec.endRec = gap_rec_id
346-
curr_sec.endTime = pred_times[gap_rec_id]
347-
n_samples = np.sum(ncsMemMap["nb_valid"][curr_sec.startRec : gap_rec_id + 1])
348-
curr_sec.n_samples = n_samples
349-
350-
next_sec = NcsSection(gap_rec_id + 1, ncsMemMap["timestamp"][gap_rec_id + 1], -1, -1, -1)
351-
ncsSects.sects.append(next_sec)
352-
353-
curr_sec = ncsSects.sects[-1]
354-
curr_sec.endRec = len(ncsMemMap["timestamp"]) - 1
355-
curr_sec.endTime = pred_times[-1]
356-
n_samples = np.sum(ncsMemMap["nb_valid"][curr_sec.startRec :])
357-
curr_sec.n_samples = n_samples
358-
359-
# calculate the estimated frequency of the block with the most samples
360-
max_blk_idx = np.argmax([bl.endRec - bl.startRec for bl in ncsSects.sects])
361-
max_blk = ncsSects.sects[max_blk_idx]
362-
363-
maxBlkFreqEstimate = (
364-
(max_blk.n_samples - ncsMemMap["nb_valid"][max_blk.endRec])
365-
* 1e6
366-
/ (ncsMemMap["timestamp"][max_blk.endRec] - max_blk.startTime)
367-
)
368-
369-
ncsSects.sampFreqUsed = maxBlkFreqEstimate
370-
ncsSects.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq(maxBlkFreqEstimate)
371-
# free memory that is unnecessarily occupied by the memmap
372-
# (see https://github.com/numpy/numpy/issues/19340)
373-
del ncsMemMap
374-
return ncsSects
375-
376-
@staticmethod
377-
def _buildForMaxGap(ncsMemMap, nomFreq):
378-
"""
379-
Determine sections of records in memory mapped Ncs file given a nominal frequency of
380-
the file, using the default values of frequency tolerance and maximum gap between blocks.
381-
382-
Parameters
383-
----------
384-
ncsMemMap:
385-
memmap of Ncs file
386-
nomFreq:
387-
nominal sampling frequency used, normally from header of file
388-
389-
Returns
390-
-------
391-
NcsSections object
392-
"""
393-
nb = NcsSections()
394-
395-
numRecs = ncsMemMap.shape[0]
396-
if numRecs < 1:
397-
return nb
398-
399-
chanNum = ncsMemMap["channel_id"][0]
400-
ts0 = ncsMemMap["timestamp"][0]
401-
402-
lastBlkI = numRecs - 1
403-
lts = ncsMemMap["timestamp"][lastBlkI]
404-
lcid = ncsMemMap["channel_id"][lastBlkI]
405-
lnb = ncsMemMap["nb_valid"][lastBlkI]
406-
lsr = ncsMemMap["sample_rate"][lastBlkI]
407-
408-
# check if file is one block of records, with exact timestamp match, which may be the case
409-
numSampsForPred = NcsSection._RECORD_SIZE * lastBlkI
410-
predLastBlockStartTime = NcsSectionsFactory.calc_sample_time(nomFreq, ts0, numSampsForPred)
411-
freqInFile = math.floor(nomFreq)
412-
if lts - predLastBlockStartTime == 0 and lcid == chanNum and lsr == freqInFile:
413-
endTime = NcsSectionsFactory.calc_sample_time(nomFreq, lts, lnb)
414-
curBlock = NcsSection(0, ts0, lastBlkI, endTime, numSampsForPred)
415-
nb.sects.append(curBlock)
416-
nb.sampFreqUsed = (numSampsForPred + lnb) / (endTime - ts0) * 1e6
417-
nb.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq(nb.sampFreqUsed)
418-
419-
# otherwise parse records to determine blocks using default maximum gap length
420-
else:
421-
nb.sampFreqUsed = nomFreq
422-
nb.microsPerSampUsed = NcsSectionsFactory.get_micros_per_samp_for_freq(nb.sampFreqUsed)
423-
maxGapToAllow = round(NcsSectionsFactory._maxGapSampFrac * 1e6 / nomFreq)
424-
nb = NcsSectionsFactory._parseForMaxGap(ncsMemMap, nb, maxGapToAllow)
425-
426-
return nb
427-
428173
@staticmethod
429174
def _buildNcsGeneric(ncsMemMap, sampFreq, gapTolerance=0):
430175
"""

0 commit comments

Comments
 (0)