def psignifit(data, options): #-------------------------------------------------------------------------- #input parsing #-------------------------------------------------------------------------- # data data = np.array(data) # percent correct in data if all( np.logical_and(data[:,1] <= 1, data[:,1] >= 0)) and any(np.logical_and(data[:,1] > 0, data[:,1] < 1)): data[:,1] = round(map( lambda x, y: x*y, data[:,2],data[:,1])) # we try to convert into our notation # options if not('options' in locals()): options = {} if not('sigmoidName' in options.keys()): options['sigmoidName'] = 'norm' if not('expType' in options.keys()): options['expType'] = 'YesNo' if not('estimateType' in options.keys()): options['estimateType'] = 'MAP' if not('confP' in options.keys()): options['confP'] = [.95, .9, .68] if not('instantPlot' in options.keys()): options['instantPlot'] = 0 if not('setBordersType' in options.keys()): options['setBordersType'] = 0 if not('maxBorderValue' in options.keys()): options['maxBorderValue'] = .00001 if not('moveBorders' in options.keys()): options['moveBorders'] = 1 if not('dynamicGrid' in options.keys()): options['dynamicGrid'] = 0 if not('widthalpha' in options.keys()): options['widthalpha'] = .05 if not('threshPC' in options.keys()): options['threshPC'] = .5 if not('CImethod' in options.keys()): options['CImethod'] = 'percentiles' if not('gridSetType' in options.keys()): options['gridSetType'] = 'cumDist' if not( 'fixedPars' in options.keys()): a = np.empty((5,1)) a[:] = np.NaN options['fixedPars'] = a if not('nblocks' in options.keys()): options['nblocks'] = 25 if not('useGPU' in options.keys()): options['useGPU'] = 0 if not('poolMaxGap' in options.keys()): options['poolMaxGap'] = np.inf if not('poolMaxLength' in options.keys()): options['poolMaxLength'] = np.inf if not('poolxTol' in options.keys()): options['poolxTol'] = 0 if not('betaPrior' in options.keys()): options['betaPrior'] = 10 if not('verbose' in options.keys()): options['verbose'] = 0 if not('stimulusRange' in options.keys()): options['stimulusRange'] = 0 if not('fastOptim' in options.keys()): options['fastOptim'] = False if options['expType'] in ['2AFC', '3AFC', '4AFC']: options['expN'] = int(float(options['expType'][0])) options['expType'] = 'nAFC' if options['expType'] == 'nAFC' and not('expN' in options.keys()): raise ValueError('For nAFC experiments please also pass the number of alternatives (options.expN)') if options['expType'] == 'YesNo': if not('stepN' in options.keys()): options['stepN'] = [40,40,20,20,20] if not('mbStepN' in options.keys()): options['mbStepN'] = [25,30, 10,10,15] elif options['expType'] == 'nAFC' or options['expType'] == 'equalAsymptote': if not('stepN' in options.keys()): options['stepN'] = [40,40,20,1,20] if not('mbStepN' in options.keys()): options['mbStepN'] = [30,40,10,1,20] else: raise ValueError('You specified an illegal experiment type') assert((max(data[:,0]) - min(data[:,0]) > 0), \ 'Your data does not have variance on the x-axis! This makes fitting impossible') ''' log space sigmoids we fit these functions with a log transformed physical axis This is because it makes the paramterization easier and also the priors fit our expectations better then. The flag is needed for the setting of the parameter bounds in setBorders ''' if options['sigmoidName'] in ['Weibull','logn','weibull']: options['logspace'] = 1 assert min(data[:,0]) > 0, 'The sigmoid you specified is not defined for negative data points!' else: options['logspace'] = 0 #if range was not given take from data if len(np.ravel(options['stimulusRange'])) <=1 : if options['logspace']: options['stimulusRange'] = np.array(np.log([min(data[:,0]),max(data[:,0])])) else : options['stimulusRange'] = np.array([min(data[:,0]),max(data[:,0])]) stimRangeSet = False else: stimRangeSet = True if options['logspace']: options['stimulusRange'] = np.log(options['stimulusRange']) if not('widthmin' in options.keys()): if len(np.unique(data[:,0])) >1 and not(stimRangeSet): if options['logspace']: options['widthmin'] = min(np.diff(np.sort(np.unique(np.log(data[:,0]))))) else: options['widthmin'] = min(np.diff(np.sort(np.unique(data[:,0])))) else: options['widthmin'] = 100*np.spacing(options['stimulusRange'][1]) # add priors if options['threshPC'] != .5 and not(hasattr(options, 'priors')): warnings.warn('psignifit:TresholdPCchanged\n'\ 'You changed the percent correct corresponding to the threshold\n') if not('priors' in options.keys()): options['priors'] = p.getStandardPriors(data, options) else: priors = p.getStandardPriors(data, options) for ipar in range(5): if not(hasattr(options['priors'][ipar], '__call__')): options['priors'][ipar] = priors[ipar] p.checkPriors(data, options) if options['dynamicGrid'] and not('GridSetEval' in options.keys()): options['GridSetEval'] = 10000 if options['dynamicGrid'] and not('UniformWeight' in options.keys()): options['UniformWeight'] = 1 ''' initialize ''' #warning if many blocks were measured if (len(np.unique(data[:,0])) >= 25) and (np.ravel(options['stimulusRange']).size == 1): warnings.warn('psignifit:probablyAdaptive\n'\ 'The data you supplied contained >= 25 stimulus levels.\n'\ 'Did you sample adaptively?\n'\ 'If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n'\ 'This will allow psignifit to choose an appropriate prior.\n'\ 'For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels,\n'\ 'which is frequently invalid for adaptive procedures!') if all(data[:,2] <= 5) and (np.ravel(options['stimulusRange']).size == 1): warnings.warn('psignifit:probablyAdaptive\n'\ 'All provided data blocks contain <= 5 trials \n'\ 'Did you sample adaptively?\n'\ 'If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n'\ 'This will allow psignifit to choose an appropriate prior.\n'\ 'For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels,\n'\ 'which is frequently invalid for adaptive procedures!') #pool data if necessary: more than options.nblocks blocks or only 1 trial per block if np.max(data[:,2]) == 1 or len(data) > options['nblocks']: warnings.warn('psignifit:pooling\n'\ 'We pooled your data, to avoid problems with n=1 blocks or to save time fitting because you have a lot of blocks\n'\ 'You can force acceptance of your blocks by increasing options.nblocks') data = poolData(data, options) # create function handle of sigmoid options['sigmoidHandle'] = getSigmoidHandle(options) # borders of integration if 'borders' in options.keys(): borders = b.setBorders(data, options) options['borders'][np.isnan(options['borders'])] = borders[np.isnan(options.borders)] else: options['borders'] = b.setBorders(data,options) border_idx = np.where(np.isnan(options['fixedPars']) == False); options['borders'][border_idx[0]] = options['fixedPars'][border_idx[0]] options['borders'][border_idx[1]] = options['fixedPars'][border_idx[1]] # normalize priors to first choice of borders options['priors'] = p.normalizePriors(options) if options['moveBorders']: options['borders'] = b.moveBorders(data, options) ''' core ''' result = psignifitCore(data,options) ''' after processing ''' # check that the marginals go to nearly 0 at the borders of the grid if options['verbose'] > -5: if result['marginals'][0][0] * result['marginalsW'][0][0] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the threshold is not near 0 at the lower border.\n'\ 'This indicates that smaller Thresholds would be possible.') if result['marginals'][0][-1] * result['marginalsW'][0][-1] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the threshold is not near 0 at the upper border.\n'\ 'This indicates that your data is not sufficient to exclude much higher thresholds.\n'\ 'Refer to the paper or the manual for more info on this topic.') if result['marginals'][1][0] * result['marginalsW'][1][0] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the width is not near 0 at the lower border.\n'\ 'This indicates that your data is not sufficient to exclude much lower widths.\n'\ 'Refer to the paper or the manual for more info on this topic.') if result['marginals'][1][-1] * result['marginalsW'][1][-1] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the width is not near 0 at the lower border.\n'\ 'This indicates that your data is not sufficient to exclude much higher widths.\n'\ 'Refer to the paper or the manual for more info on this topic.') result['timestamp'] = dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S") if options['instantPlot']: plotPsych(result) #plotBayes(result) #TODO return result
options['poolMaxGap'] = np.inf options['estimateType'] = 'MAP' options['confP'] = np.array([0.95,0.9,0.68]) options['instantPlot'] = 0 options['setBordersType'] = 0 options['maxBorderValue'] = 1.000000000000000e-05 options['moveBorders'] = 1 options['dynamicGrid'] = 0 options['widthalpha'] = 0.05 options['threshPC'] = 0.5 options['CImethod'] = 'percentiles' options['gridSetType'] = 'cumDist' options['nblocks'] = 25 options['verbose'] = 0 #options['stimulusRange'] = 0 options['sigmoidHandle'] = getSigmoidHandle(options) options['fastOptim'] = 0 options['mbStepN'] = np.array([30,40,10,1,20]) options['logspace'] = 0 temp_data= importer.loadmat('variables.mat', struct_as_record=True,matlab_compatible=True) temp_options = importer.loadmat('options.mat', struct_as_record=False, squeeze_me=True) var = np.array([ 0.00466446, 0.00473373, 0, 0.5 ,0]) - logLikelihood(data, options, var) ar = np.random.random([15,10,5,3]); alpha = np.ones([15,1,1,1]) alpha = np.tile(alpha, ar.shape[1:])
def psignifit(data, optionsIn): """ main function for fitting psychometric functions function result=psignifit(data,options) This function is the user interface for fitting psychometric functions to data. pass your data in the n x 3 matrix of the form: [x-value, number correct, number of trials] options should be a dictionary in which you set the options for your fit. You can find a full overview over the options in demo002 The result of this function is a dictionary, which contains all information the program produced for your fit. You can pass this as whole to all further processing function provided with psignifit. Especially to the plot functions. You can find an explanation for all fields of the result in demo006 To get an introduction to basic usage start with demo001 """ #-------------------------------------------------------------------------- #input parsing #-------------------------------------------------------------------------- # data data = np.array(data) # percent correct in data if all( np.logical_and(data[:,1] <= 1, data[:,1] >= 0)) and any(np.logical_and(data[:,1] > 0, data[:,1] < 1)): data[:,1] = round(map( lambda x, y: x*y, data[:,2],data[:,1])) # we try to convert into our notation # options if not('optionsIn' in locals()): options = dict() else: options = _deepcopy(optionsIn) if not('sigmoidName' in options.keys()): options['sigmoidName'] = 'norm' if not('expType' in options.keys()): options['expType'] = 'YesNo' if not('estimateType' in options.keys()): options['estimateType'] = 'MAP' if not('confP' in options.keys()): options['confP'] = [.95, .9, .68] if not('instantPlot' in options.keys()): options['instantPlot'] = 0 if not('setBordersType' in options.keys()): options['setBordersType'] = 0 if not('maxBorderValue' in options.keys()): options['maxBorderValue'] = .00001 if not('moveBorders' in options.keys()): options['moveBorders'] = 1 if not('dynamicGrid' in options.keys()): options['dynamicGrid'] = 0 if not('widthalpha' in options.keys()): options['widthalpha'] = .05 if not('threshPC' in options.keys()): options['threshPC'] = .5 if not('CImethod' in options.keys()): options['CImethod'] = 'percentiles' if not('gridSetType' in options.keys()): options['gridSetType'] = 'cumDist' if not( 'fixedPars' in options.keys()): a = np.empty((5,1)) a[:] = np.NaN options['fixedPars'] = a if not('nblocks' in options.keys()): options['nblocks'] = 25 if not('useGPU' in options.keys()): options['useGPU'] = 0 if not('poolMaxGap' in options.keys()): options['poolMaxGap'] = np.inf if not('poolMaxLength' in options.keys()): options['poolMaxLength'] = np.inf if not('poolxTol' in options.keys()): options['poolxTol'] = 0 if not('betaPrior' in options.keys()): options['betaPrior'] = 10 if not('verbose' in options.keys()): options['verbose'] = 0 if not('stimulusRange' in options.keys()): options['stimulusRange'] = 0 if not('fastOptim' in options.keys()): options['fastOptim'] = False if options['expType'] in ['2AFC', '3AFC', '4AFC']: options['expN'] = int(float(options['expType'][0])) options['expType'] = 'nAFC' if options['expType'] == 'nAFC' and not('expN' in options.keys()): raise ValueError('For nAFC experiments please also pass the number of alternatives (options.expN)') if options['expType'] == 'YesNo': if not('stepN' in options.keys()): options['stepN'] = [40,40,20,20,20] if not('mbStepN' in options.keys()): options['mbStepN'] = [25,30, 10,10,15] elif options['expType'] == 'nAFC' or options['expType'] == 'equalAsymptote': if not('stepN' in options.keys()): options['stepN'] = [40,40,20,1,20] if not('mbStepN' in options.keys()): options['mbStepN'] = [30,40,10,1,20] else: raise ValueError('You specified an illegal experiment type') assert (max(data[:,0]) - min(data[:,0]) > 0), 'Your data does not have variance on the x-axis! This makes fitting impossible' ''' log space sigmoids we fit these functions with a log transformed physical axis This is because it makes the paramterization easier and also the priors fit our expectations better then. The flag is needed for the setting of the parameter bounds in setBorders ''' if options['sigmoidName'] in ['Weibull','logn','weibull']: options['logspace'] = 1 assert min(data[:,0]) > 0, 'The sigmoid you specified is not defined for negative data points!' else: options['logspace'] = 0 #if range was not given take from data if len(np.ravel(options['stimulusRange'])) <=1 : if options['logspace']: options['stimulusRange'] = np.array(np.log([min(data[:,0]),max(data[:,0])])) else : options['stimulusRange'] = np.array([min(data[:,0]),max(data[:,0])]) stimRangeSet = False else: stimRangeSet = True if options['logspace']: options['stimulusRange'] = np.log(options['stimulusRange']) if not('widthmin' in options.keys()): if len(np.unique(data[:,0])) >1 and not(stimRangeSet): if options['logspace']: options['widthmin'] = min(np.diff(np.sort(np.unique(np.log(data[:,0]))))) else: options['widthmin'] = min(np.diff(np.sort(np.unique(data[:,0])))) else: options['widthmin'] = 100*np.spacing(options['stimulusRange'][1]) # add priors if options['threshPC'] != .5 and not(hasattr(options, 'priors')): warnings.warn('psignifit:TresholdPCchanged\n'\ 'You changed the percent correct corresponding to the threshold\n') if not('priors' in options.keys()): options['priors'] = _p.getStandardPriors(data, options) else: priors = _p.getStandardPriors(data, options) for ipar in range(5): if not(hasattr(options['priors'][ipar], '__call__')): options['priors'][ipar] = priors[ipar] _p.checkPriors(data, options) if options['dynamicGrid'] and not('GridSetEval' in options.keys()): options['GridSetEval'] = 10000 if options['dynamicGrid'] and not('UniformWeight' in options.keys()): options['UniformWeight'] = 1 ''' initialize ''' #warning if many blocks were measured if (len(np.unique(data[:,0])) >= 25) and (np.ravel(options['stimulusRange']).size == 1): warnings.warn('psignifit:probablyAdaptive\n'\ 'The data you supplied contained >= 25 stimulus levels.\n'\ 'Did you sample adaptively?\n'\ 'If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n'\ 'This will allow psignifit to choose an appropriate prior.\n'\ 'For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels,\n'\ 'which is frequently invalid for adaptive procedures!') if all(data[:,2] <= 5) and (np.ravel(options['stimulusRange']).size == 1): warnings.warn('psignifit:probablyAdaptive\n'\ 'All provided data blocks contain <= 5 trials \n'\ 'Did you sample adaptively?\n'\ 'If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n'\ 'This will allow psignifit to choose an appropriate prior.\n'\ 'For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels,\n'\ 'which is frequently invalid for adaptive procedures!') #pool data if necessary: more than options.nblocks blocks or only 1 trial per block if np.max(data[:,2]) == 1 or len(data) > options['nblocks']: warnings.warn('psignifit:pooling\n'\ 'We pooled your data, to avoid problems with n=1 blocks or to save time fitting because you have a lot of blocks\n'\ 'You can force acceptance of your blocks by increasing options.nblocks') data = poolData(data, options) # create function handle of sigmoid options['sigmoidHandle'] = getSigmoidHandle(options) # borders of integration if 'borders' in options.keys(): borders = _b.setBorders(data, options) options['borders'][np.isnan(options['borders'])] = borders[np.isnan(options['borders'])] else: options['borders'] = _b.setBorders(data,options) border_idx = np.where(np.isnan(options['fixedPars']) == False); if (border_idx[0].size > 0): options['borders'][border_idx[0],0] = options['fixedPars'][border_idx[0]] options['borders'][border_idx[0],1] = options['fixedPars'][border_idx[0]] # normalize priors to first choice of borders options['priors'] = _p.normalizePriors(options) if options['moveBorders']: options['borders'] = _b.moveBorders(data, options) ''' core ''' result = psignifitCore(data,options) ''' after processing ''' # check that the marginals go to nearly 0 at the borders of the grid if options['verbose'] > -5: if result['marginals'][0][0] * result['marginalsW'][0][0] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the threshold is not near 0 at the lower border.\n'\ 'This indicates that smaller Thresholds would be possible.') if result['marginals'][0][-1] * result['marginalsW'][0][-1] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the threshold is not near 0 at the upper border.\n'\ 'This indicates that your data is not sufficient to exclude much higher thresholds.\n'\ 'Refer to the paper or the manual for more info on this topic.') if result['marginals'][1][0] * result['marginalsW'][1][0] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the width is not near 0 at the lower border.\n'\ 'This indicates that your data is not sufficient to exclude much lower widths.\n'\ 'Refer to the paper or the manual for more info on this topic.') if result['marginals'][1][-1] * result['marginalsW'][1][-1] > .001: warnings.warn('psignifit:borderWarning\n'\ 'The marginal for the width is not near 0 at the lower border.\n'\ 'This indicates that your data is not sufficient to exclude much higher widths.\n'\ 'Refer to the paper or the manual for more info on this topic.') result['timestamp'] = _dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S") if options['instantPlot']: plot.plotPsych(result) return result
def psignifit(data, options): #-------------------------------------------------------------------------- #input parsing #-------------------------------------------------------------------------- # data data = np.array(data) # percent correct in data if all( np.logical_and(data[:,1] <= 1, data[:,1] >= 0)) and any(np.logical_and(data[:,1] > 0, data[:,1] < 1)): data[:,1] = round(map( lambda x, y: x*y, data[:,2],data[:,1])) # we try to convert into our notation # options if ~(options in locals()): options = lambda:0 if ~(hasattr(options, 'sigmoidName')): options.sigmoidName = 'norm' if ~(hasattr(options, 'expType')): options.expType = 'YesNo' if ~(hasattr(options, 'estimateType')): options.estimateType = 'MAP' if ~(hasattr(options, 'confP')): options.confP = [.95, .9, .68] if ~(hasattr(options, 'instantPlot')): options.instantPlot = 0 if ~(hasattr(options, 'setBordersType')): options.setBordersType = 0 if ~(hasattr(options, 'maxBorderValue')): options.maxBorderValue = .00001 if ~(hasattr(options, 'moveBorders')): options.moveBorders = 1 if ~(hasattr(options, 'dynamicGrid')): options.dynamicGrid = 0 if ~(hasattr(options, 'widthalpha')): options.widthalpha = .05 if ~(hasattr(options, 'threshPC')): options.threshPC = .5 if ~(hasattr(options, 'CImethod')): options.CImethod = 'percentiles' if ~(hasattr(options, 'gridSetType')): options.gridSetType = 'cumDist' if ~(hasattr(options, 'fixedPars')): a = np.empty((5,1)) a[:] = np.NaN options.fixedPars = a if ~(hasattr(options, 'nblocks')): options.nblocks = 25 if ~(hasattr(options, 'useGPU')): options.useGPU = 0 if ~(hasattr(options, 'poolMaxGap')): options.poolMaxGap = np.inf if ~(hasattr(options, 'poolMaxLength')): options.poolMaxLength = np.inf if ~(hasattr(options, 'poolxTol')): options.poolxTol = 0 if ~(hasattr(options, 'betaPrior')): options.betaPrior = 10 if ~(hasattr(options, 'verbose')): options.verbose = 0 if ~(hasattr(options, 'stimulusRange')): options.stimulusRange = 0 if ~(hasattr(options, 'fastOptim')): options.fastOptim = False if options.expType in ['2AFC', '3AFC', '4AFC']: options.expN = int(float(options.expType[0])) options.expType = 'nAFC' if options.expType == 'nAFC' and ~hasattr(options,'expN'): raise ValueError('For nAFC experiments please also pass the number of alternatives (options.expN)') if options.expType == 'YesNo': if ~(hasattr(options,'stepN')): options.stepN = [40,40,20,20,20] if ~(hasattr(options, 'mbStepN')): options.mbStepN = [25,20, 10,10,15] elif options.expType == 'nAFC' or options.expType == 'equalAsymptote': if ~(hasattr(options,'stepN')): options.stepN = [40,40,20,1,20] if ~(hasattr(options, 'mbStepN')): options.mbStepN = [30,30,10,1,20] else: raise ValueError('You specified an illegal experiment type') #assert(max(data[:,0]) > min(data[:,0]), TODO check if that is really meant this way #'Your data does not have variance on the x-axis! This makes fitting impossible') ''' log space sigmoids we fit these functions with a log transformed physical axis This is because it makes the paramterization easier and also the priors fit our expectations better then. The flag is needed for the setting of the parameter bounds in setBorders ''' if options.sigmoidName in ['Weibull','logn','weibull']: options.logspace = 1 assert min(data[:,0]) > 0, 'The sigmoid you specified is not defined for negative data points!' else: options.logspace = 0 # add priors if options.threshPC != .5 and not(hasattr(options, 'priors')): warnings.warn('psignifit:TresholdPCchanged\n You changed the percent correct corresponding to the threshold\n') if ~hasattr(options, 'priors'): options.priors = p.getStandardPriors(data, options) else: #TODO do I need to check for cell? priors = p.getStandardPriors(data, options) for ipar in range(5): if not(hasattr(options.priors[ipar], '__call__')): options.priors[ipar] = priors[ipar] p.checkPriors(data, options) if options.dynamicGrid and not(hasattr(options, 'GridSetEval')): options.GridSetEval = 10000 if options.dynamicGrid and not(hasattr(options, 'UniformWeight')): options.UniformWeight = 1 ''' initialize ''' #warning if many blocks were measured if (len(np.unique(data[:,0])) >= 25) and (np.ravel(options.stimulusRange) == 1): warnings.warn('psignifit:probablyAdaptive\n The data you supplied contained >= 25 stimulus levels.\n Did you sample adaptively?\n If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n This will allow psignifit to choose an appropriate prior.\n For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels\n, which is frequently invalid for adaptive procedures!') if all(data[:,2] <= 5) and (np.ravel(options.stimulusRange) == 1): warnings.warn('psignifit:probablyAdaptive\n All provided data blocks contain <= 5 trials \n Did you sample adaptively?\n If so please specify a range which contains the whole psychometric function in options.stimulusRange.\n This will allow psignifit to choose an appropriate prior.\n For now we use the standard heuristic, assuming that the psychometric function is covered by the stimulus levels\n, which is frequently invalid for adaptive procedures!') #pool data if necessary: more than options.nblocks blocks or only 1 trial per block if np.max(data[:,2]) == 1 or len(data) > options.nblocks: warnings.warn('psignifit:pooling\n We pooled your data, to avoid problems with n=1 blocks or to save time fitting because you have a lot of blocks\n You can force acceptence of your blocks by increasing options.nblocks') data = poolData(data, options) options.nblocks = len(data) # create function handle of sigmoid options.sigmoidHandle = getSigmoidHandle(options) # borders of integration if hasattr(options, 'borders'): borders = b.setBorders(data, options) options.borders[np.isnan(options.borders)] = borders[np.isnan(options.borders)] else: options.borders = b.setBorders(data,options) options.borders[not(np.isnan(options.fixedPars)),0] = options.fixedPars[not(np.isnan(options.fixedPars))] options.borders[not(np.isnan(options.fixedPars)),1] = options.fixedPars[not(np.isnan(options.fixedPars))] # normalize priors to first hoice of borders options.priors = p.normalizePriors(options) if options.moveBorders: options.borders = b.moveBorders(data, options) ''' core ''' result = psignifitCore(data,options) ''' after processing ''' # check that the marginals go to nearly 0 at the borders of the grid if options.verbose > -5: #TODO check if result.marginals[0][0] * result.marginalsW[0][0] > .001: warnings.warn('psignifit:borderWarning\n The marginal for the threshold is not near 0 at the lower border\n This indicates that smaller Thresholds would be possible') if result.marginals[0][-1] * result.marginalsW[0][-1] > .001: warnings.warn('psignifit:borderWarning\n The marginal for the threshold is not near 0 at the upper border\n This indicates that your data is not sufficient to exclude much higher thresholds.\n Refer to the paper or the manual for more info on this topic') if result.marginals[1][0] * result.marginalsW[1][0] > .001: warnings.warn('psignifit:borderWarning\n The marginal for the width is not near 0 at the lower border\n This indicates that your data is not sufficient to exclude much lower widths.\n Refer to the paper or the manual for more info on this topic') if result.marginals[1][-1] * result.marginalsW[1][-1] > .001: warnings.warn('psignifit:borderWarning\n The marginal for the width is not near 0 at the lower border\n This indicates that your data is not sufficient to exclude much higher widths.\n Refer to the paper or the manual for more info on this topic') result.timestamp = dt.now().strftime("%Y-%m-%d %H:%M:%S") #if options.instantPlot: #plotPsych(result) #plotBayes(result) TODO implement and uncomment return result