├── src ├── __init__.py └── FIRDeconvolution.py ├── requirements.txt ├── MANIFEST.in ├── .gitignore ├── LICENSE ├── test ├── data │ ├── blink_dict.csv │ └── sac_dict.csv └── test.py ├── README.md └── setup.py /src/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.1' 2 | 3 | from .FIRDeconvolution import FIRDeconvolution 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.9.3 2 | pandas==0.16.1 3 | scikit-learn==0.16.1 4 | scipy==0.16.0 5 | seaborn==0.5.1 6 | statsmodels==0.5.0 -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # include *.rst 2 | include *.md 3 | include src/__init__.py 4 | # recursive-include doc * 5 | recursive-include src *.py 6 | # recursive-include src/test *.dat 7 | recursive-include src/test *.py 8 | recursive-include src/test *.ipynb -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # Apple shit 60 | .DS_Store 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Tomas Knapen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /test/data/blink_dict.csv: -------------------------------------------------------------------------------- 1 | ,duration,start_timestamp,eye,end_timestamp 2 | 0,92.0,13877767.0,L,13877858.0 3 | 1,98.0,13891386.0,L,13891483.0 4 | 2,94.0,13907576.0,L,13907669.0 5 | 3,63.0,13917312.0,L,13917374.0 6 | 4,4.0,13931805.0,L,13931808.0 7 | 5,24.0,13931829.0,L,13931852.0 8 | 6,79.0,13946820.0,L,13946898.0 9 | 7,110.0,13958046.0,L,13958155.0 10 | 8,70.0,13971211.0,L,13971280.0 11 | 9,68.0,13982676.0,L,13982743.0 12 | 10,50.0,13993889.0,L,13993938.0 13 | 11,102.0,13999344.0,L,13999445.0 14 | 12,65.0,14012939.0,L,14013003.0 15 | 13,80.0,14020685.0,L,14020764.0 16 | 14,59.0,14026094.0,L,14026152.0 17 | 15,131.0,14037589.0,L,14037719.0 18 | 16,124.0,14056168.0,L,14056291.0 19 | 17,140.0,14068626.0,L,14068765.0 20 | 18,105.0,14084195.0,L,14084299.0 21 | 19,132.0,14097825.0,L,14097956.0 22 | 20,79.0,14112909.0,L,14112987.0 23 | 21,107.0,14113297.0,L,14113403.0 24 | 22,123.0,14129453.0,L,14129575.0 25 | 23,109.0,14129739.0,L,14129847.0 26 | 24,231.0,14153912.0,L,14154142.0 27 | 25,74.0,14154276.0,L,14154349.0 28 | 26,109.0,14154525.0,L,14154633.0 29 | 27,103.0,14174658.0,L,14174760.0 30 | 28,91.0,14195541.0,L,14195631.0 31 | 29,78.0,14221326.0,L,14221403.0 32 | 30,103.0,14247809.0,L,14247911.0 33 | 31,122.0,14270480.0,L,14270601.0 34 | 32,101.0,14288782.0,L,14288882.0 35 | 33,97.0,14308552.0,L,14308648.0 36 | 34,101.0,14344424.0,L,14344524.0 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FIRDeconvolution 2 | FIRDeconvolution is a python class that performs finite impulse response fitting on time series data, in order to estimate event-related signals. 3 | 4 | 5 | Example use cases are fMRI and pupil size analysis. The package performs the linear least squares analysis using numpy.linalg as a backend, but can switch between different backends, such as statsmodels (which is implemented). For very collinear design matrices ridge regression is implemented through the sklearn RidgeCV function. Bootstrap estimates of error regions are implemented through residual reshuffling. 6 | 7 | 8 | It is possible to add covariates to the events to estimate not just the impulse response function, but also correlation timecourses with secondary variables. Furthermore, one can add the duration each event should have in the designmatrix, for designs in which the durations of the events vary. 9 | 10 | 11 | In neuroscience, the inspection of the event-related signals such as those estimated by FIRDeconvolution is essential for a thorough understanding of one's data. Researchers may overlook essential patterns in their data when blindly running GLM analyses without looking at the impulse response shapes. 12 | 13 | 14 | The test notebook explains how the package can be used for data analysis, by creating toy signals and then using FIRDeconvolution to fit the impulse response functions from the toy data. 15 | 16 | 17 | ## Dependencies 18 | numpy, scipy, matplotlib, statsmodels, sklearn 19 | 20 | TODO 21 | - temporal autocorrelation correction 22 | 23 | 24 | 25 | 26 | 27 | [![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.46216.svg)](http://dx.doi.org/10.5281/zenodo.46216) 28 | 29 | 30 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # 3 | 4 | import os 5 | from os import path as op 6 | 7 | import setuptools # noqa; we are using a setuptools namespace 8 | from numpy.distutils.core import setup 9 | 10 | # get the version 11 | version = None 12 | with open(os.path.join('src', '__init__.py'), 'r') as fid: 13 | for line in (line.strip() for line in fid): 14 | if line.startswith('__version__'): 15 | version = line.split('=')[1].strip().strip('\'') 16 | break 17 | if version is None: 18 | raise RuntimeError('Could not determine version') 19 | 20 | 21 | descr = """Finite Impulse Response package for time series analysis.""" 22 | 23 | DISTNAME = 'fir' 24 | DESCRIPTION = descr 25 | MAINTAINER = 'Tomas Knapen' 26 | MAINTAINER_EMAIL = 'tknapen@gmail.com' 27 | URL = 'http://tknapen.github.io/FIRDeconvolution' 28 | LICENSE = 'The MIT License (MIT)' 29 | DOWNLOAD_URL = 'https://github.com/tknapen/FIRDeconvolution' 30 | VERSION = version 31 | 32 | if __name__ == "__main__": 33 | if os.path.exists('MANIFEST'): 34 | os.remove('MANIFEST') 35 | 36 | setup(name=DISTNAME, 37 | maintainer=MAINTAINER, 38 | include_package_data=True, 39 | maintainer_email=MAINTAINER_EMAIL, 40 | description=DESCRIPTION, 41 | license=LICENSE, 42 | url=URL, 43 | version=VERSION, 44 | download_url=DOWNLOAD_URL, 45 | long_description=open('README.md').read(), 46 | zip_safe=False, # the package can run out of an .egg file 47 | classifiers=['Intended Audience :: Science/Research', 48 | 'Intended Audience :: Developers', 49 | 'License :: OSI Approved', 50 | 'Programming Language :: Python', 51 | 'Topic :: Software Development', 52 | 'Topic :: Scientific/Engineering', 53 | 'Operating System :: POSIX', 54 | 'Operating System :: Unix', 55 | 'Operating System :: MacOS'], 56 | platforms='any', 57 | packages=['fir'], 58 | package_dir={'fir': 'src'}, 59 | package_data={'fir': ['test/*.ipynb']} #, 60 | # scripts=['bin/fir'] 61 | ) -------------------------------------------------------------------------------- /test/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | """ 4 | EyeLinkSession.py 5 | 6 | Created by Tomas Knapen on 2011-04-27. 7 | Copyright (c) 2011 __MyCompanyName__. All rights reserved. 8 | """ 9 | 10 | from __future__ import division 11 | 12 | import numpy as np 13 | import scipy as sp 14 | 15 | import matplotlib.pyplot as pl 16 | # %matplotlib inline 17 | # %pylab osx 18 | 19 | import seaborn as sn 20 | sn.set(style="ticks") 21 | 22 | from FIRDeconvolution import FIRDeconvolution 23 | 24 | # signal parameters 25 | signal_sample_frequency = 15 26 | event_1_gain, event_2_gain = 2.3, 0.85 27 | noise_gain = 0.75 28 | 29 | # deconvolution parameters 30 | deconv_sample_frequency = 3.0 31 | deconvolution_interval = [-5, 25] 32 | 33 | # how many time points to plot in figures 34 | plot_time = 8000 35 | 36 | # create some exponentially distributed random ISI events (Dale, 1999) of which we will create and deconvolve responses. 37 | period_durs = np.random.gamma(4.0,1.5,size = 600) 38 | events = period_durs.cumsum() 39 | events_1, events_2 = events[0::2], events[1::2] 40 | 41 | durations_1, durations_2 = np.random.gamma(1.9,0.25,size = events_1.shape[0]), np.random.gamma(1.9,0.25,size = events_2.shape[0]) 42 | 43 | # these events are scaled with their own underlying covariate. 44 | # for instance, you could have a model-based variable that scales the signal on a per-trial basis. 45 | events_gains_1 = np.random.randn(len(events_1))*0.4 46 | events_gains_2 = np.random.randn(len(events_2))*2.4 47 | 48 | # We create an IRF, using a standard BOLD response. 49 | 50 | def double_gamma_with_d(x, a1 = 6, a2 = 12, b1 = 0.9, b2 = 0.9, c = 0.35,d1=5.4,d2=10.8): 51 | return np.array([(t/(d1))**a1 * np.exp(-(t-d1)/b1) - c*(t/(d2))**a2 * np.exp(-(t-d2)/b2) for t in x]) 52 | 53 | hrf_1 = double_gamma_with_d(np.linspace(0,25,25*signal_sample_frequency), a1 = 4.5, a2 = 10, d1 = 5.0, d2 = 10.0) 54 | hrf_2 = double_gamma_with_d(np.linspace(0,25,25*signal_sample_frequency), a1 = 1.5, a2 = 10, d1 = 3.0, d2 = 10.0) 55 | # hrf = hrf/np.abs(hrf).sum() 56 | 57 | f = pl.figure(figsize = (10,4)) 58 | pl.plot(np.linspace(0,25,25*signal_sample_frequency), hrf_1, 'g') 59 | pl.plot(np.linspace(0,25,25*signal_sample_frequency), hrf_2, 'b') 60 | pl.axhline(0, lw=0.5, color = 'k') 61 | sn.despine() 62 | 63 | # Using this IRF we're going to create two signals 64 | # signal gains are determined by random covariate and a standard gain 65 | # we mix them all together with some noise, injected on the signal, not the events. 66 | 67 | times = np.arange(0,events.max()+45.0,1.0/signal_sample_frequency) 68 | 69 | event_1_in_times = np.array([((times>te) * (timeste) * (times self.resampled_signal_size: 154 | self.logger.debug('deconv samples are continuing after the data stops.') 155 | valid = False 156 | if eti > self.resampled_signal_size: 157 | self.logger.debug('event falls outside of the scope of the data.') 158 | valid = False 159 | 160 | if valid: # only incorporate sensible events. 161 | # calculate the design matrix that belongs to this event. 162 | this_event_design_matrix = (np.diag(np.ones(self.deconvolution_interval_size)) * cov) 163 | over_durations_dm = np.copy(this_event_design_matrix) 164 | if dur > 1: # if this event has a non-unity duration, duplicate the stick regressors in the time direction 165 | for d in np.arange(1,dur): 166 | over_durations_dm[d:] += this_event_design_matrix[:-d] 167 | # and correct for differences in durations between different regressor types. 168 | over_durations_dm /= mean_duration 169 | # add the designmatrix for this event to the full design matrix for this type of event. 170 | regressors_for_event[:,eti:int(eti+self.deconvolution_interval_size)] += over_durations_dm 171 | 172 | return regressors_for_event 173 | 174 | def create_design_matrix(self, demean = False, intercept = True): 175 | """create_design_matrix calls create_event_regressors for each of the covariates in the self.covariates dict. self.designmatrix is created and is shaped (nr_regressors, self.resampled_signal.shape[-1]) 176 | """ 177 | self.design_matrix = np.zeros((int(self.number_of_event_types*self.deconvolution_interval_size), self.resampled_signal_size)) 178 | 179 | for i, covariate in enumerate(self.covariates.keys()): 180 | # document the creation of the designmatrix step by step 181 | self.logger.debug('creating regressor for ' + covariate) 182 | indices = np.arange(i*self.deconvolution_interval_size,(i+1)*self.deconvolution_interval_size, dtype = int) 183 | # here, we implement the dot-separated encoding of events and covariates 184 | if len(covariate.split('.')) > 0: 185 | which_event_time_indices = covariate.split('.')[0] 186 | else: 187 | which_event_time_indices = covariate 188 | self.design_matrix[indices] = self.create_event_regressors( self.event_times_indices[which_event_time_indices], 189 | self.covariates[covariate], 190 | self.durations[which_event_time_indices]) 191 | 192 | if demean: 193 | # we expect the data to be demeaned. 194 | # it's an option whether the regressors should be, too 195 | self.design_matrix = (self.design_matrix.T - self.design_matrix.mean(axis = -1)).T 196 | if intercept: 197 | # similarly, intercept is a choice. 198 | self.design_matrix = np.vstack((self.design_matrix, np.ones((1,self.design_matrix.shape[-1])))) 199 | 200 | self.logger.debug('created %s design_matrix' % (str(self.design_matrix.shape))) 201 | 202 | def add_continuous_regressors_to_design_matrix(self, regressors): 203 | """add_continuous_regressors_to_design_matrix appends continuously sampled regressors to the existing design matrix. One uses this addition to the design matrix when one expects the data to contain nuisance factors that aren't tied to the moments of specific events. For instance, in fMRI analysis this allows us to add cardiac / respiratory regressors, as well as tissue and head motion timecourses to the designmatrix. 204 | 205 | :param regressors: the signal to be appended to the design matrix. 206 | :type regressors: numpy array, with shape equal to (nr_regressors, self.resampled_signal.shape[-1]) 207 | """ 208 | previous_design_matrix_shape = self.design_matrix.shape 209 | if len(regressors.shape) == 1: 210 | regressors = regressors[np.newaxis, :] 211 | if regressors.shape[1] != self.resampled_signal.shape[1]: 212 | self.logger.warning('additional regressor shape %s does not conform to designmatrix shape %s' % (regressors.shape, self.resampled_signal.shape)) 213 | # and, an vstack append 214 | self.design_matrix = np.vstack((self.design_matrix, regressors)) 215 | self.logger.debug('added %s continuous regressors to %s design_matrix, shape now %s' % (str(regressors.shape), str(previous_design_matrix_shape), str(self.design_matrix.shape))) 216 | 217 | def regress(self, method = 'lstsq'): 218 | """regress performs linear least squares regression of the designmatrix on the data. 219 | 220 | :param method: method, or backend to be used for the regression analysis. 221 | :type method: string, one of ['lstsq', 'sm_ols'] 222 | :returns: instance variables 'betas' (nr_betas x nr_signals) and 'residuals' (nr_signals x nr_samples) are created. 223 | """ 224 | 225 | if method is 'lstsq': 226 | self.betas, residuals_sum, rank, s = LA.lstsq(self.design_matrix.T, self.resampled_signal.T) 227 | self.residuals = self.resampled_signal - self.predict_from_design_matrix(self.design_matrix) 228 | elif method is 'sm_ols': 229 | import statsmodels.api as sm 230 | 231 | assert self.resampled_signal.shape[0] == 1, \ 232 | 'signal input into statsmodels OLS cannot contain multiple signals at once, present shape %s' % str(self.resampled_signal.shape) 233 | model = sm.OLS(np.squeeze(self.resampled_signal),self.design_matrix.T) 234 | results = model.fit() 235 | # make betas and residuals that are compatible with the LA.lstsq type. 236 | self.betas = np.array(results.params).reshape((self.design_matrix.shape[0], self.resampled_signal.shape[0])) 237 | self.residuals = np.array(results.resid).reshape(self.resampled_signal.shape) 238 | 239 | self.logger.debug('performed %s regression on %s design_matrix and %s signal' % (method, str(self.design_matrix.shape), str(self.resampled_signal.shape))) 240 | 241 | def ridge_regress(self, cv = 20, alphas = None ): 242 | """perform k-folds cross-validated ridge regression on the design_matrix. To be used when the design matrix contains very collinear regressors. For cross-validation and ridge fitting, we use sklearn's RidgeCV functionality. Note: intercept is not fit, and data are not prenormalized. 243 | 244 | :param cv: cross-validated folds, inherits RidgeCV cv argument's functionality. 245 | :type cv: int, standard = 20 246 | :param alphas: values of penalization parameter to be traversed by the procedure, inherits RidgeCV cv argument's functionality. Standard value, when parameter is None, is np.logspace(7, 0, 20) 247 | :type alphas: numpy array, from >0 to 1. 248 | :returns: instance variables 'betas' (nr_betas x nr_signals) and 'residuals' (nr_signals x nr_samples) are created. 249 | """ 250 | if alphas is None: 251 | alphas = np.logspace(7, 0, 20) 252 | self.rcv = linear_model.RidgeCV(alphas=alphas, 253 | fit_intercept=False, 254 | cv=cv) 255 | self.rcv.fit(self.design_matrix.T, self.resampled_signal.T) 256 | 257 | self.betas = self.rcv.coef_.T 258 | self.residuals = self.resampled_signal - self.rcv.predict(self.design_matrix.T) 259 | 260 | self.logger.debug('performed ridge regression on %s design_matrix and %s signal, resulting alpha value is %f' % (str(self.design_matrix.shape), str(self.resampled_signal.shape), self.rcv.alpha_)) 261 | 262 | def betas_for_cov(self, covariate = '0'): 263 | """betas_for_cov returns the beta values (i.e. IRF) associated with a specific covariate. 264 | 265 | :param covariate: name of covariate. 266 | :type covariate: string 267 | """ 268 | # find the index in the designmatrix of the current covariate 269 | this_covariate_index = list(self.covariates.keys()).index(covariate) 270 | return self.betas[int(this_covariate_index*self.deconvolution_interval_size):int((this_covariate_index+1)*self.deconvolution_interval_size)] 271 | 272 | def betas_for_events(self): 273 | """betas_for_events creates an internal self.betas_per_event_type array, of (nr_covariates x self.devonvolution_interval_size), 274 | which holds the outcome betas per event type,in the order generated by self.covariates.keys() 275 | """ 276 | self.betas_per_event_type = np.zeros((len(self.covariates), self.deconvolution_interval_size, self.resampled_signal.shape[0])) 277 | for i, covariate in enumerate(self.covariates.keys()): 278 | self.betas_per_event_type[i] = self.betas_for_cov(covariate) 279 | 280 | def predict_from_design_matrix(self, design_matrix): 281 | """predict_from_design_matrix predicts signals given a design matrix. 282 | 283 | :param design_matrix: design matrix from which to predict a signal. 284 | :type design_matrix: numpy array, (nr_samples x betas.shape) 285 | :returns: predicted signal(s) 286 | :rtype: numpy array (nr_signals x nr_samples) 287 | """ 288 | # check if we have already run the regression - which is necessary 289 | assert hasattr(self, 'betas'), 'no betas found, please run regression before prediction' 290 | assert design_matrix.shape[0] == self.betas.shape[0], \ 291 | 'designmatrix needs to have the same number of regressors as the betas already calculated' 292 | 293 | # betas = np.copy(self.betas.T, order="F", dtype = np.float32) 294 | # f_design_matrix = np.copy(design_matrix, order = "F", dtype = np.float32) 295 | 296 | prediction = np.dot(self.betas.astype(np.float32).T, design_matrix.astype(np.float32)) 297 | 298 | return prediction 299 | 300 | def calculate_rsq(self): 301 | """calculate_rsq calculates coefficient of determination, or r-squared, defined here as 1.0 - SS_res / SS_tot. rsq is only calculated for those timepoints in the data for which the design matrix is non-zero. 302 | """ 303 | assert hasattr(self, 'betas'), 'no betas found, please run regression before rsq' 304 | 305 | explained_times = self.design_matrix.sum(axis = 0) != 0 306 | 307 | explained_signal = self.predict_from_design_matrix(self.design_matrix) 308 | self.rsq = 1.0 - np.sum((explained_signal[:,explained_times] - self.resampled_signal[:,explained_times])**2, axis = -1) / np.sum(self.resampled_signal[:,explained_times].squeeze()**2, axis = -1) 309 | self.ssr = np.sum((explained_signal[:,explained_times] - self.resampled_signal[:,explained_times])**2, axis = -1) 310 | return np.squeeze(self.rsq) 311 | 312 | def bootstrap_on_residuals(self, nr_repetitions = 1000): 313 | """bootstrap_on_residuals bootstraps, by shuffling the residuals. bootstrap_on_residuals should only be used on single-channel data, as otherwise the memory load might increase too much. This uses the lstsq backend regression for a single-pass fit across repetitions. Please note that shuffling the residuals may change the autocorrelation of the bootstrap samples relative to that of the original data and that may reduce its validity. Reference: https://en.wikipedia.org/wiki/Bootstrapping_(statistics)#Resampling_residuals 314 | 315 | :param nr_repetitions: number of repetitions for the bootstrap. 316 | :type nr_repetitions: int 317 | 318 | """ 319 | assert self.resampled_signal.shape[0] == 1, \ 320 | 'signal input into bootstrap_on_residuals cannot contain signals from multiple channels at once, present shape %s' % str(self.resampled_signal.shape) 321 | assert hasattr(self, 'betas'), 'no betas found, please run regression before bootstrapping' 322 | 323 | # create bootstrap data by taking the residuals 324 | bootstrap_data = np.zeros((self.resampled_signal_size, nr_repetitions)) 325 | explained_signal = self.predict_from_design_matrix(self.design_matrix).T 326 | 327 | for x in range(bootstrap_data.shape[-1]): # loop over bootstrapsamples 328 | bootstrap_data[:,x] = (self.residuals.T[np.random.permutation(self.resampled_signal_size)] + explained_signal).squeeze() 329 | 330 | self.bootstrap_betas, bs_residuals, rank, s = LA.lstsq(self.design_matrix.T, bootstrap_data) 331 | 332 | self.bootstrap_betas_per_event_type = np.zeros((len(self.covariates), self.deconvolution_interval_size, nr_repetitions)) 333 | 334 | for i, covariate in enumerate(list(self.covariates.keys())): 335 | # find the index in the designmatrix of the current covariate 336 | this_covariate_index = list(self.covariates.keys()).index(covariate) 337 | self.bootstrap_betas_per_event_type[i] = self.bootstrap_betas[this_covariate_index*self.deconvolution_interval_size:(this_covariate_index+1)*self.deconvolution_interval_size] 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | -------------------------------------------------------------------------------- /test/data/sac_dict.csv: -------------------------------------------------------------------------------- 1 | ,peak_velocity,start_timestamp,end_x,eye,start_x,start_y,duration,length,end_y,end_timestamp 2 | 0,149.0,13870600.0,965.5,L,959.8,554.4,21.0,2.2,619.0,13870620.0 3 | 1,251.0,13870785.0,852.8,L,962.8,632.2,25.0,3.18,645.6,13870809.0 4 | 2,226.0,13871072.0,978.1,L,845.8,644.6,28.0,3.79,638.7,13871099.0 5 | 3,66.0,13871560.0,1015.9,L,988.8,646.4,14.0,0.79,642.0,13871573.0 6 | 4,63.0,13871752.0,999.1,L,1018.4,643.1,10.0,0.57,646.8,13871761.0 7 | 5,58.0,13871961.0,1025.0,L,996.8,650.3,17.0,0.81,650.9,13871977.0 8 | 6,184.0,13872355.0,949.6,L,1026.3,656.2,23.0,2.21,647.9,13872377.0 9 | 7,67.0,13872576.0,987.7,L,961.1,650.2,14.0,0.77,653.0,13872589.0 10 | 8,216.0,13872764.0,939.5,L,990.2,653.9,35.0,4.07,542.0,13872798.0 11 | 9,46.0,13874279.0,931.0,L,940.0,547.0,16.0,0.26,546.8,13874294.0 12 | 10,43.0,13876763.0,928.9,L,937.9,555.2,6.0,0.26,554.6,13876768.0 13 | 11,1606.0,13877731.0,914.6,L,938.3,558.1,175.0,0.91,540.5,13877905.0 14 | 12,51.0,13878027.0,929.0,L,913.3,547.5,10.0,0.45,548.0,13878036.0 15 | 13,35.0,13879424.0,909.8,L,916.0,560.8,7.0,0.22,556.9,13879430.0 16 | 14,143.0,13880712.0,909.5,L,915.2,554.7,19.0,1.77,606.7,13880730.0 17 | 15,180.0,13880844.0,984.7,L,905.2,619.5,23.0,2.29,627.3,13880866.0 18 | 16,270.0,13882032.0,881.7,L,998.2,630.6,35.0,5.23,512.2,13882066.0 19 | 17,110.0,13882281.0,929.9,L,880.6,491.4,26.0,2.11,537.4,13882306.0 20 | 18,65.0,13883683.0,926.2,L,946.4,555.4,10.0,0.58,554.2,13883692.0 21 | 19,44.0,13885783.0,922.0,L,928.9,571.4,6.0,0.22,568.3,13885788.0 22 | 20,53.0,13889295.0,910.6,L,926.7,571.7,10.0,0.47,569.4,13889304.0 23 | 21,1414.0,13891314.0,907.7,L,903.0,547.5,232.0,0.14,546.1,13891545.0 24 | 22,39.0,13892797.0,932.2,L,939.8,534.1,6.0,0.24,536.7,13892802.0 25 | 23,43.0,13894917.0,911.9,L,918.3,565.3,17.0,0.2,567.3,13894933.0 26 | 24,63.0,13896338.0,902.1,L,918.6,573.9,18.0,0.49,569.7,13896355.0 27 | 25,195.0,13898189.0,836.0,L,912.9,569.8,23.0,2.35,594.1,13898211.0 28 | 26,190.0,13900656.0,907.0,L,844.1,629.1,23.0,2.57,575.1,13900678.0 29 | 27,64.0,13901193.0,906.4,L,912.0,555.6,10.0,0.57,539.6,13901202.0 30 | 28,99.0,13901282.0,907.9,L,908.8,532.8,31.0,0.59,550.2,13901312.0 31 | 29,46.0,13904275.0,891.1,L,902.3,557.3,7.0,0.33,555.0,13904281.0 32 | 30,47.0,13905778.0,895.9,L,908.0,555.8,8.0,0.35,553.9,13905785.0 33 | 31,2192.0,13907539.0,915.4,L,911.8,546.2,182.0,0.71,525.6,13907720.0 34 | 32,39.0,13907889.0,908.4,L,910.6,535.3,6.0,0.26,542.7,13907894.0 35 | 33,57.0,13912289.0,896.4,L,913.6,555.4,10.0,0.51,551.4,13912298.0 36 | 34,46.0,13912464.0,918.0,L,905.8,550.3,8.0,0.35,549.8,13912471.0 37 | 35,190.0,13914631.0,858.1,L,921.9,554.1,22.0,2.36,598.3,13914652.0 38 | 36,214.0,13915308.0,987.5,L,847.1,625.5,34.0,4.02,626.7,13915341.0 39 | 37,1615.0,13917276.0,944.0,L,988.3,636.6,159.0,2.54,571.8,13917434.0 40 | 38,228.0,13917674.0,825.4,L,940.3,575.7,36.0,3.84,517.1,13917709.0 41 | 39,165.0,13917903.0,890.2,L,829.4,512.1,22.0,2.24,553.5,13917924.0 42 | 40,53.0,13918769.0,913.9,L,902.5,566.0,10.0,0.48,555.6,13918778.0 43 | 41,42.0,13919369.0,905.0,L,913.2,546.8,6.0,0.26,543.8,13919374.0 44 | 42,73.0,13924529.0,899.5,L,917.2,552.9,19.0,0.52,549.1,13924547.0 45 | 43,54.0,13924663.0,923.6,L,908.9,546.7,9.0,0.44,550.2,13924671.0 46 | 44,41.0,13927403.0,909.8,L,919.7,551.9,7.0,0.28,551.5,13927409.0 47 | 45,137.0,13930022.0,865.2,L,915.6,544.9,34.0,1.64,521.8,13930055.0 48 | 46,55.0,13930473.0,913.6,L,897.8,538.7,13.0,0.62,551.3,13930485.0 49 | 47,160.0,13931020.0,860.4,L,911.4,537.8,20.0,1.93,574.9,13931039.0 50 | 48,299.0,13931211.0,976.5,L,853.1,604.5,25.0,3.62,628.3,13931235.0 51 | 49,59.0,13931412.0,993.3,L,979.8,632.2,10.0,0.5,622.7,13931421.0 52 | 50,2750.0,13931760.0,939.1,L,990.4,615.5,159.0,2.58,553.2,13931918.0 53 | 51,129.0,13934450.0,895.8,L,922.0,583.2,23.0,1.07,560.9,13934472.0 54 | 52,38.0,13934690.0,902.4,L,896.9,555.4,6.0,0.23,550.5,13934695.0 55 | 53,40.0,13935292.0,908.8,L,914.7,534.1,6.0,0.23,529.7,13935297.0 56 | 54,74.0,13940562.0,894.2,L,908.0,560.1,18.0,0.4,559.1,13940579.0 57 | 55,44.0,13944618.0,902.2,L,911.1,573.2,6.0,0.28,569.6,13944623.0 58 | 56,1444.0,13946771.0,898.9,L,918.2,557.9,193.0,0.56,554.7,13946963.0 59 | 57,104.0,13947944.0,862.7,L,902.8,566.5,15.0,1.15,569.8,13947958.0 60 | 58,83.0,13947989.0,882.6,L,868.9,583.4,12.0,0.83,605.0,13948000.0 61 | 59,256.0,13948114.0,991.5,L,880.3,608.9,25.0,3.24,626.4,13948138.0 62 | 60,233.0,13951498.0,929.9,L,992.8,634.8,24.0,2.53,582.7,13951521.0 63 | 61,98.0,13952026.0,905.4,L,929.4,574.8,16.0,1.06,551.0,13952041.0 64 | 62,72.0,13955108.0,890.0,L,908.9,553.4,18.0,0.54,553.9,13955125.0 65 | 63,52.0,13955270.0,912.5,L,898.8,560.1,8.0,0.4,558.4,13955277.0 66 | 64,48.0,13956100.0,891.7,L,904.2,555.0,8.0,0.36,553.5,13956107.0 67 | 65,47.0,13956669.0,893.2,L,905.4,557.2,8.0,0.35,555.6,13956676.0 68 | 66,102.0,13957899.0,895.5,L,909.3,543.8,37.0,0.5,552.8,13957935.0 69 | 67,1960.0,13958017.0,907.5,L,914.7,527.3,190.0,0.27,532.6,13958206.0 70 | 68,56.0,13960104.0,909.7,L,921.8,549.5,16.0,0.39,544.0,13960119.0 71 | 69,44.0,13961144.0,912.0,L,922.0,544.0,7.0,0.3,546.9,13961150.0 72 | 70,41.0,13961606.0,919.0,L,910.3,544.8,6.0,0.25,546.1,13961611.0 73 | 71,154.0,13963649.0,992.2,L,915.8,569.1,24.0,2.51,605.5,13963672.0 74 | 72,63.0,13963791.0,990.5,L,992.4,615.3,11.0,0.58,632.3,13963801.0 75 | 73,169.0,13964753.0,920.8,L,996.4,622.4,21.0,2.17,618.0,13964773.0 76 | 74,162.0,13968117.0,937.2,L,930.6,624.1,23.0,2.09,562.9,13968139.0 77 | 75,48.0,13970198.0,907.2,L,916.6,570.8,7.0,0.32,565.8,13970204.0 78 | 76,1456.0,13971157.0,910.8,L,919.3,551.7,180.0,0.35,559.2,13971336.0 79 | 77,43.0,13971641.0,928.6,L,918.4,558.5,7.0,0.3,557.2,13971647.0 80 | 78,46.0,13972158.0,924.1,L,933.0,540.0,6.0,0.26,540.7,13972163.0 81 | 79,42.0,13973711.0,907.5,L,915.0,556.0,6.0,0.24,552.7,13973716.0 82 | 80,64.0,13974762.0,911.4,L,923.9,550.7,19.0,0.38,546.8,13974780.0 83 | 81,57.0,13976149.0,915.4,L,929.9,559.7,17.0,0.42,557.4,13976165.0 84 | 82,42.0,13981714.0,898.2,L,907.3,573.4,6.0,0.28,576.3,13981719.0 85 | 83,1371.0,13982633.0,913.9,L,903.4,582.7,172.0,0.87,558.8,13982804.0 86 | 84,135.0,13984186.0,887.7,L,927.3,555.1,23.0,1.18,545.7,13984208.0 87 | 85,71.0,13984464.0,917.3,L,894.6,542.8,12.0,0.73,552.5,13984475.0 88 | 86,95.0,13984837.0,899.0,L,924.1,549.5,20.0,0.72,548.8,13984856.0 89 | 87,46.0,13985933.0,881.7,L,889.2,552.9,17.0,0.22,553.8,13985949.0 90 | 88,41.0,13987185.0,846.2,L,854.2,559.3,6.0,0.25,562.4,13987190.0 91 | 89,104.0,13987751.0,833.5,L,854.4,555.4,22.0,0.61,552.4,13987772.0 92 | 90,180.0,13989118.0,837.3,L,872.0,562.5,24.0,2.01,510.9,13989141.0 93 | 91,58.0,13989348.0,840.9,L,843.0,514.5,10.0,0.5,499.8,13989357.0 94 | 92,209.0,13989650.0,990.9,L,845.7,490.9,34.0,4.16,496.5,13989683.0 95 | 93,280.0,13989851.0,980.2,L,992.3,496.8,27.0,3.87,610.3,13989877.0 96 | 94,295.0,13990319.0,998.2,L,994.7,630.5,26.0,4.12,509.1,13990344.0 97 | 95,276.0,13990562.0,848.9,L,987.4,490.6,27.0,3.96,492.4,13990588.0 98 | 96,252.0,13991875.0,835.7,L,845.4,487.7,26.0,3.56,592.4,13991900.0 99 | 97,1287.0,13993843.0,951.2,L,858.2,609.8,147.0,4.31,510.1,13993989.0 100 | 98,152.0,13994894.0,905.0,L,953.9,508.3,20.0,1.83,473.8,13994913.0 101 | 99,140.0,13995154.0,955.4,L,907.6,474.9,18.0,1.66,502.5,13995171.0 102 | 100,95.0,13995580.0,927.8,L,960.0,489.3,15.0,0.99,499.5,13995594.0 103 | 101,56.0,13996266.0,934.8,L,937.2,512.1,10.0,0.54,527.8,13996275.0 104 | 102,1768.0,13999322.0,933.4,L,946.5,525.2,165.0,0.77,545.0,13999486.0 105 | 103,65.0,13999734.0,942.6,L,942.3,547.1,12.0,0.71,526.3,13999745.0 106 | 104,43.0,14000926.0,920.0,L,929.2,535.7,6.0,0.26,536.4,14000931.0 107 | 105,70.0,14005870.0,900.5,L,915.7,556.9,18.0,0.44,555.4,14005887.0 108 | 106,56.0,14006038.0,921.5,L,906.5,562.4,8.0,0.43,561.2,14006045.0 109 | 107,62.0,14007421.0,903.0,L,920.7,561.3,19.0,0.51,562.6,14007439.0 110 | 108,175.0,14011514.0,871.3,L,927.0,559.2,20.0,1.97,593.3,14011533.0 111 | 109,104.0,14011569.0,962.4,L,914.9,622.6,14.0,1.39,631.1,14011582.0 112 | 110,96.0,14011702.0,1007.5,L,978.3,635.9,15.0,0.96,621.8,14011716.0 113 | 111,2085.0,14012900.0,915.1,L,981.3,627.8,162.0,2.13,599.5,14013061.0 114 | 112,134.0,14013601.0,992.9,L,940.8,607.1,18.0,1.49,607.2,14013618.0 115 | 113,228.0,14014321.0,916.5,L,991.5,614.4,22.0,2.56,573.6,14014342.0 116 | 114,74.0,14014826.0,907.8,L,920.0,577.7,12.0,0.73,558.7,14014837.0 117 | 115,44.0,14015421.0,917.5,L,913.1,557.2,6.0,0.23,551.7,14015426.0 118 | 116,68.0,14016016.0,903.1,L,919.0,548.3,19.0,0.46,550.2,14016034.0 119 | 117,166.0,14018391.0,869.9,L,907.3,547.7,21.0,2.0,597.4,14018411.0 120 | 118,316.0,14018576.0,956.9,L,854.9,607.6,31.0,4.7,499.0,14018606.0 121 | 119,71.0,14018760.0,983.8,L,965.6,488.9,11.0,0.69,475.6,14018770.0 122 | 120,161.0,14020051.0,914.1,L,984.4,469.2,20.0,2.15,491.5,14020070.0 123 | 121,1643.0,14020649.0,948.3,L,932.3,480.8,158.0,0.56,471.1,14020806.0 124 | 122,85.0,14021651.0,930.2,L,950.5,482.8,13.0,0.9,502.8,14021663.0 125 | 123,57.0,14022759.0,904.6,L,922.0,521.6,10.0,0.51,524.0,14022768.0 126 | 124,45.0,14024777.0,914.6,L,917.9,533.3,17.0,0.11,534.7,14024793.0 127 | 125,42.0,14025274.0,921.9,L,930.9,536.2,7.0,0.27,538.2,14025280.0 128 | 126,2237.0,14026062.0,910.4,L,921.8,530.2,136.0,0.73,549.5,14026197.0 129 | 127,44.0,14028837.0,914.8,L,921.1,557.9,17.0,0.18,558.6,14028853.0 130 | 128,42.0,14029289.0,937.5,L,928.9,549.5,6.0,0.27,546.5,14029294.0 131 | 129,45.0,14029731.0,919.2,L,927.5,539.5,16.0,0.24,540.6,14029746.0 132 | 130,44.0,14030825.0,928.7,L,919.5,558.0,6.0,0.27,559.8,14030830.0 133 | 131,51.0,14031266.0,913.0,L,926.7,556.8,9.0,0.42,552.2,14031274.0 134 | 132,79.0,14033318.0,887.6,L,911.3,545.9,20.0,0.68,545.0,14033337.0 135 | 133,93.0,14033795.0,876.2,L,907.5,545.2,13.0,0.92,539.6,14033807.0 136 | 134,87.0,14034153.0,908.8,L,889.3,515.0,15.0,0.94,537.3,14034167.0 137 | 135,167.0,14036924.0,998.1,L,923.9,542.6,36.0,2.99,604.4,14036959.0 138 | 136,1141.0,14037550.0,963.9,L,1003.8,615.5,215.0,2.01,566.8,14037764.0 139 | 137,269.0,14038024.0,884.3,L,960.7,577.2,40.0,3.6,493.1,14038063.0 140 | 138,133.0,14038269.0,946.4,L,886.7,492.5,24.0,2.33,539.2,14038292.0 141 | 139,123.0,14039126.0,907.9,L,959.9,562.7,20.0,1.54,550.8,14039145.0 142 | 140,67.0,14039372.0,943.3,L,918.0,551.9,14.0,0.76,544.8,14039385.0 143 | 141,76.0,14039817.0,916.1,L,930.8,554.2,19.0,0.57,543.1,14039835.0 144 | 142,46.0,14040990.0,916.8,L,928.1,544.3,8.0,0.34,541.5,14040997.0 145 | 143,52.0,14042965.0,908.0,L,921.7,546.4,8.0,0.39,546.9,14042972.0 146 | 144,64.0,14046492.0,920.1,L,942.4,545.0,12.0,0.64,543.4,14046503.0 147 | 145,42.0,14046938.0,931.0,L,922.3,552.5,7.0,0.27,549.6,14046944.0 148 | 146,119.0,14051961.0,882.7,L,920.9,527.3,19.0,1.11,533.3,14051979.0 149 | 147,59.0,14052013.0,884.8,L,890.0,515.2,8.0,0.42,503.5,14052020.0 150 | 148,78.0,14052286.0,898.3,L,873.4,504.0,13.0,0.8,514.7,14052298.0 151 | 149,135.0,14052319.0,896.5,L,895.6,514.9,44.0,0.5,529.7,14052362.0 152 | 150,86.0,14052765.0,878.1,L,907.8,528.2,13.0,0.88,521.6,14052777.0 153 | 151,87.0,14053024.0,930.1,L,892.0,522.5,16.0,1.1,527.5,14053039.0 154 | 152,165.0,14053970.0,847.2,L,921.0,528.5,23.0,2.12,522.6,14053992.0 155 | 153,84.0,14054169.0,880.3,L,850.5,522.7,13.0,0.88,529.3,14054181.0 156 | 154,68.0,14054504.0,861.2,L,882.2,535.3,10.0,0.6,534.7,14054513.0 157 | 155,1290.0,14056140.0,970.1,L,861.6,522.4,194.0,3.96,594.7,14056333.0 158 | 156,92.0,14056437.0,1002.7,L,968.5,598.4,14.0,1.01,591.2,14056450.0 159 | 157,283.0,14058455.0,931.5,L,1002.0,610.5,31.0,2.53,565.6,14058485.0 160 | 158,62.0,14059087.0,930.5,L,934.5,548.7,12.0,0.66,529.6,14059098.0 161 | 159,41.0,14060137.0,908.9,L,916.3,544.1,6.0,0.21,543.7,14060142.0 162 | 160,72.0,14064118.0,904.0,L,923.0,557.7,19.0,0.55,555.8,14064136.0 163 | 161,56.0,14064365.0,929.2,L,915.5,559.2,16.0,0.4,560.7,14064380.0 164 | 162,61.0,14068130.0,918.5,L,937.1,547.3,10.0,0.53,546.3,14068139.0 165 | 163,42.0,14068279.0,933.8,L,924.6,545.3,7.0,0.27,546.7,14068285.0 166 | 164,1918.0,14068588.0,929.0,L,930.4,546.6,222.0,0.33,536.9,14068809.0 167 | 165,92.0,14072670.0,907.3,L,938.8,541.6,20.0,0.9,542.5,14072689.0 168 | 166,159.0,14074158.0,897.5,L,953.9,535.7,23.0,1.82,511.2,14074180.0 169 | 167,107.0,14074415.0,929.7,L,916.1,482.3,17.0,1.22,516.4,14074431.0 170 | 168,196.0,14079273.0,995.8,L,927.1,541.2,25.0,2.7,486.7,14079297.0 171 | 169,72.0,14079468.0,999.8,L,989.0,485.3,12.0,0.76,465.0,14079479.0 172 | 170,207.0,14080472.0,918.5,L,994.6,471.7,24.0,2.89,527.7,14080495.0 173 | 171,73.0,14082770.0,924.9,L,908.3,557.7,13.0,0.78,539.4,14082782.0 174 | 172,1155.0,14084162.0,919.2,L,923.9,537.2,183.0,0.25,543.3,14084344.0 175 | 173,95.0,14084539.0,914.3,L,930.7,544.4,18.0,0.86,523.2,14084556.0 176 | 174,59.0,14087929.0,911.4,L,929.6,540.9,10.0,0.52,539.2,14087938.0 177 | 175,39.0,14088469.0,930.8,L,922.6,549.5,6.0,0.24,549.0,14088474.0 178 | 176,43.0,14089874.0,913.1,L,921.4,544.0,6.0,0.25,546.0,14089879.0 179 | 177,45.0,14091906.0,910.0,L,919.4,545.9,7.0,0.31,541.5,14091912.0 180 | 178,57.0,14095949.0,896.4,L,910.9,568.4,18.0,0.48,561.4,14095966.0 181 | 179,114.0,14097274.0,958.5,L,900.0,552.0,28.0,2.46,605.0,14097301.0 182 | 180,1106.0,14097785.0,955.8,L,999.4,607.9,212.0,1.56,580.3,14097996.0 183 | 181,220.0,14098242.0,901.9,L,970.9,595.2,22.0,2.46,552.3,14098263.0 184 | 182,130.0,14098744.0,961.5,L,907.9,550.3,19.0,1.56,558.0,14098762.0 185 | 183,149.0,14100711.0,918.2,L,951.9,569.4,24.0,1.22,547.6,14100734.0 186 | 184,84.0,14105690.0,914.8,L,933.4,543.3,19.0,0.55,539.0,14105708.0 187 | 185,90.0,14108411.0,885.1,L,913.0,556.5,20.0,0.81,559.7,14108430.0 188 | 186,99.0,14108470.0,908.5,L,900.6,549.0,24.0,0.53,563.1,14108493.0 189 | 187,174.0,14112285.0,1002.7,L,927.8,542.7,30.0,2.93,484.1,14112314.0 190 | 188,300.0,14112459.0,877.7,L,996.6,492.1,29.0,4.65,585.2,14112487.0 191 | 189,70.0,14112661.0,849.6,L,867.0,600.4,12.0,0.69,614.6,14112672.0 192 | 190,1198.0,14112875.0,883.6,L,855.9,605.0,156.0,1.95,552.4,14113030.0 193 | 191,1900.0,14113273.0,859.6,L,877.0,523.9,185.0,0.55,517.2,14113457.0 194 | 192,129.0,14113673.0,881.7,L,875.6,523.3,18.0,1.56,569.0,14113690.0 195 | 193,196.0,14116177.0,911.8,L,868.4,601.0,23.0,2.09,551.5,14116199.0 196 | 194,205.0,14119843.0,909.9,L,939.4,539.7,54.0,0.85,538.9,14119896.0 197 | 195,44.0,14120159.0,932.8,L,921.8,546.5,7.0,0.32,545.6,14120165.0 198 | 196,50.0,14120450.0,921.7,L,935.1,542.1,8.0,0.39,540.9,14120457.0 199 | 197,50.0,14120633.0,948.3,L,936.9,539.1,7.0,0.33,539.5,14120639.0 200 | 198,50.0,14123729.0,920.2,L,931.8,552.6,17.0,0.33,552.0,14123745.0 201 | 199,51.0,14124157.0,947.5,L,932.5,550.1,9.0,0.43,549.6,14124165.0 202 | 200,40.0,14125668.0,937.6,L,931.0,545.1,6.0,0.25,540.3,14125673.0 203 | 201,44.0,14126184.0,936.7,L,941.8,534.9,17.0,0.18,537.9,14126200.0 204 | 202,153.0,14127745.0,874.4,L,919.9,544.3,22.0,1.97,587.8,14127766.0 205 | 203,51.0,14127904.0,847.2,L,856.5,596.0,8.0,0.4,604.9,14127911.0 206 | 204,78.0,14128251.0,921.7,L,861.5,601.8,30.0,1.74,595.5,14128280.0 207 | 205,184.0,14128437.0,848.5,L,918.6,597.9,22.0,2.03,606.8,14128458.0 208 | 206,1567.0,14129419.0,882.6,L,852.2,591.8,209.0,3.0,507.3,14129627.0 209 | 207,1714.0,14129712.0,864.5,L,886.9,509.7,183.0,0.64,509.5,14129894.0 210 | 208,179.0,14130106.0,972.4,L,893.2,505.1,25.0,2.56,540.1,14130130.0 211 | 209,154.0,14130575.0,931.1,L,991.5,548.9,20.0,1.77,538.2,14130594.0 212 | 210,55.0,14130856.0,947.3,L,938.7,540.5,9.0,0.45,529.6,14130864.0 213 | 211,54.0,14136694.0,911.8,L,925.8,547.8,8.0,0.41,545.3,14136701.0 214 | 212,95.0,14139309.0,896.2,L,920.1,561.9,21.0,0.69,560.5,14139329.0 215 | 213,51.0,14139683.0,913.0,L,898.6,560.8,9.0,0.42,559.3,14139691.0 216 | 214,138.0,14143540.0,852.0,L,913.0,543.2,21.0,1.96,569.7,14143560.0 217 | 215,41.0,14143756.0,842.9,L,844.9,596.6,7.0,0.27,604.5,14143762.0 218 | 216,102.0,14146863.0,814.3,L,846.6,615.7,17.0,1.14,595.8,14146879.0 219 | 217,72.0,14146917.0,846.7,L,831.2,584.0,9.0,0.59,572.5,14146925.0 220 | 218,178.0,14147175.0,924.8,L,858.6,566.3,22.0,2.05,543.7,14147196.0 221 | 219,94.0,14147811.0,935.1,L,941.0,531.5,12.0,0.81,554.7,14147822.0 222 | 220,66.0,14150399.0,909.5,L,921.2,534.2,20.0,0.35,537.6,14150418.0 223 | 221,62.0,14150768.0,923.5,L,905.4,539.0,9.0,0.52,538.1,14150776.0 224 | 222,126.0,14151287.0,883.2,L,931.0,538.9,21.0,1.38,535.0,14151307.0 225 | 223,49.0,14151570.0,912.7,L,898.8,535.3,9.0,0.4,536.9,14151578.0 226 | 224,63.0,14151615.0,902.8,L,913.8,527.2,18.0,0.33,524.3,14151632.0 227 | 225,52.0,14152949.0,915.2,L,930.1,536.5,9.0,0.43,537.0,14152957.0 228 | 226,59.0,14153795.0,922.4,L,937.4,531.6,17.0,0.43,532.5,14153811.0 229 | 227,1672.0,14153888.0,907.4,L,923.3,519.7,292.0,0.68,534.5,14154179.0 230 | 228,1675.0,14154258.0,910.6,L,929.5,526.6,131.0,1.42,488.1,14154388.0 231 | 229,1480.0,14154506.0,921.5,L,916.8,498.4,161.0,1.06,529.3,14154666.0 232 | 230,50.0,14154857.0,950.1,L,938.5,531.2,7.0,0.33,530.0,14154863.0 233 | 231,52.0,14155460.0,939.2,L,950.2,534.7,16.0,0.32,533.7,14155475.0 234 | 232,53.0,14155823.0,950.5,L,936.3,543.1,8.0,0.41,541.3,14155830.0 235 | 233,44.0,14156325.0,926.6,L,937.3,543.7,7.0,0.31,544.0,14156331.0 236 | 234,51.0,14158361.0,922.5,L,931.2,544.7,17.0,0.26,542.5,14158377.0 237 | 235,131.0,14159975.0,962.0,L,920.8,547.8,24.0,1.97,594.2,14159998.0 238 | 236,60.0,14160231.0,1011.6,L,993.1,615.0,10.0,0.54,618.4,14160240.0 239 | 237,165.0,14160884.0,966.0,L,1018.8,614.0,20.0,1.79,585.8,14160903.0 240 | 238,135.0,14162383.0,898.9,L,949.4,573.5,19.0,1.53,558.9,14162401.0 241 | 239,55.0,14163070.0,926.7,L,911.6,563.7,16.0,0.56,553.4,14163085.0 242 | 240,63.0,14166675.0,906.7,L,922.8,549.4,9.0,0.52,542.5,14166683.0 243 | 241,73.0,14173673.0,916.4,L,930.6,576.0,19.0,0.5,567.7,14173691.0 244 | 242,1487.0,14174619.0,899.3,L,928.5,549.6,178.0,0.93,537.8,14174796.0 245 | 243,57.0,14174936.0,922.9,L,906.6,546.2,9.0,0.47,548.7,14174944.0 246 | 244,54.0,14177086.0,929.8,L,941.7,551.5,17.0,0.35,553.1,14177102.0 247 | 245,49.0,14177346.0,943.3,L,932.1,557.3,7.0,0.34,560.3,14177352.0 248 | 246,178.0,14178909.0,871.4,L,930.5,544.1,22.0,2.36,592.7,14178930.0 249 | 247,240.0,14182868.0,928.7,L,884.5,608.9,21.0,2.46,546.9,14182888.0 250 | 248,58.0,14185343.0,927.8,L,941.9,547.7,18.0,0.41,546.1,14185360.0 251 | 249,45.0,14187836.0,913.3,L,923.8,553.4,7.0,0.3,554.0,14187842.0 252 | 250,48.0,14189824.0,921.5,L,932.2,550.2,16.0,0.32,552.4,14189839.0 253 | 251,104.0,14195376.0,932.6,L,943.4,531.6,26.0,0.87,555.5,14195401.0 254 | 252,1462.0,14195511.0,944.0,L,948.9,522.4,164.0,0.15,524.0,14195674.0 255 | 253,73.0,14199381.0,917.6,L,927.2,540.4,20.0,0.3,543.7,14199400.0 256 | 254,162.0,14201120.0,860.6,L,912.7,556.7,19.0,1.86,589.3,14201138.0 257 | 255,220.0,14204175.0,933.7,L,856.9,608.9,24.0,2.65,565.1,14204198.0 258 | 256,59.0,14204479.0,910.8,L,928.9,563.5,11.0,0.55,557.9,14204489.0 259 | 257,84.0,14207462.0,932.1,L,949.6,541.6,21.0,0.5,542.2,14207482.0 260 | 258,200.0,14208796.0,853.3,L,919.1,540.6,21.0,2.25,576.9,14208816.0 261 | 259,60.0,14209006.0,864.7,L,854.0,593.4,10.0,0.53,606.3,14209015.0 262 | 260,207.0,14209518.0,941.5,L,872.0,602.8,24.0,2.5,558.4,14209541.0 263 | 261,172.0,14210306.0,899.0,L,932.8,563.1,24.0,1.22,541.3,14210329.0 264 | 262,87.0,14210986.0,930.9,L,909.5,540.4,19.0,0.61,541.1,14211004.0 265 | 263,54.0,14211621.0,913.9,L,919.8,541.9,18.0,0.23,546.4,14211638.0 266 | 264,166.0,14213073.0,846.8,L,902.2,559.1,20.0,1.94,591.9,14213092.0 267 | 265,115.0,14213639.0,897.4,L,850.4,594.7,18.0,1.38,603.7,14213656.0 268 | 266,92.0,14215094.0,852.8,L,890.6,605.0,18.0,1.14,594.1,14215111.0 269 | 267,168.0,14216589.0,927.6,L,889.9,607.3,23.0,2.12,553.5,14216611.0 270 | 268,57.0,14217725.0,905.9,L,923.4,542.7,10.0,0.5,543.3,14217734.0 271 | 269,42.0,14219146.0,915.2,L,925.4,536.6,7.0,0.29,536.3,14219152.0 272 | 270,89.0,14221084.0,887.8,L,934.9,540.6,23.0,1.64,568.2,14221106.0 273 | 271,1026.0,14221257.0,880.0,L,880.4,587.9,183.0,0.49,602.2,14221439.0 274 | 272,124.0,14221874.0,936.0,L,886.8,603.0,17.0,1.48,590.0,14221890.0 275 | 273,131.0,14223790.0,911.4,L,915.0,580.2,22.0,1.36,540.2,14223811.0 276 | 274,44.0,14224316.0,922.7,L,917.7,541.1,8.0,0.29,533.6,14224323.0 277 | 275,59.0,14225357.0,919.8,L,929.2,539.9,18.0,0.28,537.5,14225374.0 278 | 276,124.0,14229012.0,884.1,L,930.6,549.0,20.0,1.69,579.6,14229031.0 279 | 277,136.0,14229761.0,921.0,L,870.9,592.4,30.0,1.44,591.1,14229790.0 280 | 278,85.0,14229829.0,914.6,L,923.2,576.6,18.0,1.1,545.0,14229846.0 281 | 279,62.0,14233137.0,907.8,L,922.3,550.5,8.0,0.48,543.3,14233144.0 282 | 280,44.0,14234167.0,923.7,L,934.3,544.1,7.0,0.31,543.0,14234173.0 283 | 281,102.0,14235387.0,895.1,L,924.1,548.9,19.0,1.39,581.7,14235405.0 284 | 282,168.0,14236169.0,836.8,L,903.9,597.2,21.0,1.95,607.8,14236189.0 285 | 283,186.0,14236844.0,919.5,L,840.9,605.4,22.0,2.29,592.5,14236865.0 286 | 284,149.0,14239599.0,905.5,L,922.9,593.1,23.0,1.52,551.0,14239621.0 287 | 285,45.0,14242711.0,918.8,L,928.5,545.9,17.0,0.28,546.6,14242727.0 288 | 286,44.0,14243409.0,922.2,L,922.6,551.2,17.0,0.04,552.2,14243425.0 289 | 287,162.0,14247316.0,921.6,L,928.5,530.5,34.0,0.69,511.2,14247349.0 290 | 288,297.0,14247372.0,930.0,L,917.3,490.5,54.0,2.4,560.2,14247425.0 291 | 289,910.0,14247789.0,951.0,L,936.8,534.4,157.0,0.41,534.7,14247945.0 292 | 290,61.0,14250935.0,903.0,L,919.3,537.3,19.0,0.47,536.2,14250953.0 293 | 291,52.0,14254428.0,908.3,L,922.7,542.5,9.0,0.41,542.6,14254436.0 294 | 292,42.0,14255464.0,917.5,L,926.2,542.2,6.0,0.25,541.4,14255469.0 295 | 293,62.0,14260465.0,924.6,L,940.8,538.4,18.0,0.47,540.9,14260482.0 296 | 294,172.0,14261786.0,856.8,L,926.8,534.3,23.0,2.22,562.5,14261808.0 297 | 295,197.0,14263931.0,907.7,L,845.1,583.5,25.0,2.19,546.5,14263955.0 298 | 296,61.0,14264333.0,920.4,L,905.1,553.2,11.0,0.57,542.3,14264343.0 299 | 297,53.0,14266077.0,929.2,L,943.4,536.6,8.0,0.41,537.5,14266084.0 300 | 298,59.0,14268374.0,916.3,L,935.2,537.9,11.0,0.55,536.0,14268384.0 301 | 299,231.0,14269951.0,849.2,L,928.3,533.4,23.0,2.72,578.0,14269973.0 302 | 300,1014.0,14270439.0,903.9,L,869.6,591.5,202.0,1.45,560.2,14270640.0 303 | 301,108.0,14272793.0,914.9,L,886.0,578.5,17.0,1.24,551.4,14272809.0 304 | 302,87.0,14273288.0,912.3,L,904.1,559.4,15.0,0.87,534.7,14273302.0 305 | 303,70.0,14279508.0,898.3,L,904.5,535.3,19.0,0.23,539.4,14279526.0 306 | 304,59.0,14280396.0,923.0,L,940.8,542.2,10.0,0.54,537.4,14280405.0 307 | 305,43.0,14280931.0,938.2,L,928.3,541.9,7.0,0.3,545.0,14280937.0 308 | 306,168.0,14282484.0,868.3,L,929.5,542.2,20.0,1.97,568.7,14282503.0 309 | 307,174.0,14283379.0,924.2,L,865.2,562.6,21.0,2.0,531.4,14283399.0 310 | 308,91.0,14285794.0,914.8,L,947.4,534.9,14.0,0.93,534.9,14285807.0 311 | 309,53.0,14288422.0,961.4,L,975.1,535.8,8.0,0.4,533.3,14288429.0 312 | 310,46.0,14288591.0,977.4,L,966.8,534.9,7.0,0.3,535.1,14288597.0 313 | 311,714.0,14288759.0,961.4,L,974.7,521.3,162.0,0.39,518.4,14288920.0 314 | 312,85.0,14291805.0,925.2,L,946.8,529.0,19.0,0.64,533.2,14291823.0 315 | 313,66.0,14292793.0,946.1,L,925.7,534.1,10.0,0.59,533.4,14292802.0 316 | 314,41.0,14298333.0,955.0,L,963.7,529.4,6.0,0.25,530.7,14298338.0 317 | 315,58.0,14302895.0,921.5,L,929.3,534.3,18.0,0.26,530.2,14302912.0 318 | 316,920.0,14308526.0,941.2,L,943.4,520.9,163.0,0.08,522.2,14308688.0 319 | 317,47.0,14309416.0,950.0,L,961.6,528.6,8.0,0.36,524.2,14309423.0 320 | 318,93.0,14313212.0,906.0,L,926.4,540.1,21.0,0.63,533.3,14313232.0 321 | 319,77.0,14316687.0,932.9,L,918.3,530.0,19.0,0.42,528.8,14316705.0 322 | 320,50.0,14318609.0,910.6,L,921.3,530.3,7.0,0.32,533.2,14318615.0 323 | 321,44.0,14326236.0,923.0,L,914.8,561.9,6.0,0.26,558.9,14326241.0 324 | 322,56.0,14328220.0,923.9,L,939.2,544.2,11.0,0.54,534.9,14328230.0 325 | 323,37.0,14330184.0,957.4,L,948.4,543.0,16.0,0.29,539.2,14330199.0 326 | 324,45.0,14335935.0,954.2,L,971.0,530.0,12.0,0.5,526.0,14335946.0 327 | 325,199.0,14337756.0,857.0,L,941.6,529.6,24.0,2.83,573.0,14337779.0 328 | 326,60.0,14337975.0,879.0,L,862.0,596.1,10.0,0.53,602.4,14337984.0 329 | 327,74.0,14338139.0,858.2,L,883.1,607.8,11.0,0.71,607.7,14338149.0 330 | 328,113.0,14340256.0,854.7,L,850.2,594.4,17.0,1.33,555.3,14340272.0 331 | 329,136.0,14340654.0,920.5,L,864.5,559.2,20.0,1.71,542.1,14340673.0 332 | 330,92.0,14343066.0,925.8,L,926.2,535.9,15.0,1.06,567.1,14343080.0 333 | 331,117.0,14343918.0,876.1,L,943.8,593.3,23.0,1.95,598.4,14343940.0 334 | 332,1121.0,14344398.0,903.5,L,876.4,587.7,160.0,0.78,591.0,14344557.0 335 | 333,68.0,14345398.0,941.1,L,911.6,594.9,19.0,1.01,578.8,14345416.0 336 | 334,117.0,14346395.0,912.3,L,934.1,569.8,19.0,1.44,531.6,14346413.0 337 | 335,49.0,14347003.0,910.9,L,922.7,535.9,8.0,0.37,531.3,14347010.0 338 | 336,50.0,14348496.0,918.0,L,924.6,532.7,18.0,0.19,533.0,14348513.0 339 | 337,53.0,14349543.0,920.2,L,932.5,535.6,18.0,0.35,535.3,14349560.0 340 | 338,167.0,14351406.0,853.1,L,905.6,543.8,20.0,1.71,568.1,14351425.0 341 | 339,148.0,14354694.0,885.3,L,838.6,583.6,21.0,1.73,551.3,14354714.0 342 | 340,40.0,14355410.0,917.9,L,910.0,549.2,6.0,0.23,550.0,14355415.0 343 | 341,61.0,14355610.0,894.7,L,905.8,555.6,19.0,0.33,553.0,14355628.0 344 | 342,53.0,14356641.0,889.3,L,901.6,560.2,17.0,0.36,558.5,14356657.0 345 | 343,39.0,14357080.0,910.3,L,902.4,557.4,6.0,0.25,554.0,14357085.0 346 | 344,45.0,14359374.0,919.6,L,930.5,542.1,7.0,0.31,543.0,14359380.0 347 | 345,106.0,14364196.0,900.1,L,925.7,555.9,21.0,0.74,554.2,14364216.0 348 | 346,39.0,14364408.0,920.6,L,913.0,554.4,6.0,0.23,552.3,14364413.0 349 | 347,51.0,14369304.0,921.6,L,934.7,536.9,8.0,0.4,532.7,14369311.0 350 | 348,94.0,14371030.0,876.7,L,906.9,533.8,34.0,1.47,498.9,14371063.0 351 | 349,110.0,14371292.0,903.8,L,889.0,500.8,18.0,1.32,537.4,14371309.0 352 | 350,86.0,14371996.0,892.0,L,921.8,551.3,14.0,0.9,542.9,14372009.0 353 | 351,52.0,14372407.0,909.1,L,895.2,540.9,9.0,0.43,545.6,14372415.0 354 | 352,93.0,14378043.0,878.5,L,893.2,534.9,22.0,0.49,542.4,14378064.0 355 | 353,71.0,14378320.0,925.4,L,907.3,517.1,12.0,0.72,531.8,14378331.0 356 | --------------------------------------------------------------------------------