def test_walk_stack(self): def deeper(): return list(traceback.walk_stack(None)) s1 = list(traceback.walk_stack(None)) s2 = deeper() self.assertEqual(len(s2) - len(s1), 1) self.assertEqual(s2[1:], s1)
def extract_stack(f=None, limit=None): """Replacement for traceback.extract_stack() that only does the necessary work for asyncio debug mode. """ if f is None: f = sys._getframe().f_back if limit is None: # Limit the amount of work to a reasonable amount, as extract_stack() # can be called for each coroutine and future in debug mode. limit = constants.DEBUG_STACK_DEPTH stack = traceback.StackSummary.extract(traceback.walk_stack(f), limit=limit, lookup_lines=False) stack.reverse() return stack
def test_extract_stack_limit(self): s = traceback.StackSummary.extract(traceback.walk_stack(None), limit=5) self.assertEqual(len(s), 5)
def test_walk_stack(self): s = list(traceback.walk_stack(None)) self.assertGreater(len(s), 10)
def deeper(): return list(traceback.walk_stack(None))
def analyse(obj, *params, bypassLundeby=False, plotLundebyResults=False, suppressWarnings=False, IREndManualCut=None, **kwargs): #TODO: Fix formating """ Receives an one channel SignalObj or ImpulsiveResponse and calculate the room acoustic parameters especified in the positional input arguments. :param obj: one channel impulsive response :type obj: SignalObj or ImpulsiveResponse Input parameters for reverberation time, 'RT': :param RTdecay: decay interval for RT calculation. e.g. 20 :type RTdecay: int Input parameters for clarity, 'C': TODO Input parameters for definition, 'D': TODO Input parameters for strength factor, 'G': TODO :param nthOct: number of fractions per octave :type nthOct: int :param minFreq: analysis inferior frequency limit :type minFreq: float :param maxFreq: analysis superior frequency limit :type maxFreq: float :param bypassLundeby: bypass lundeby correction to False :type bypassLundeby: bool, optional :param plotLundebyResults: plot the Lundeby correction parameters, defaults to False :type plotLundebyResults: bool, optional :param suppressWarnings: suppress the warnings fro mthe Lundeby correction, defaults to False :type suppressWarnings: bool, optional :return: Analysis object with the calculated parameter :rtype: Analysis """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames is (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() if not isinstance(obj, SignalObj) and not isinstance( obj, ImpulsiveResponse): raise TypeError("'obj' must be an one channel SignalObj or" + " ImpulsiveResponse.") if isinstance(obj, ImpulsiveResponse): SigObj = obj.systemSignal else: SigObj = obj if SigObj.numChannels > 1: raise TypeError("'obj' can't contain more than one channel.") samplingRate = SigObj.samplingRate SigObj = crop_IR(SigObj, IREndManualCut) listEDC = cumulative_integration(SigObj, bypassLundeby, plotLundebyResults, suppressWarnings=suppressWarnings, **kwargs) for _ in params: if 'RT' in params: RTdecay = params[params.index('RT') + 1] nthOct = kwargs['nthOct'] RT = reverberation_time(RTdecay, nthOct, samplingRate, listEDC) result = Analysis(anType='RT', nthOct=nthOct, minBand=kwargs['minFreq'], maxBand=kwargs['maxFreq'], data=RT) # if 'C' in prm: # Ctemp = prm[1] # if 'D' in prm: # Dtemp = prm[1] result.creation_name = creation_name return result
def G_Lpe(IR, nthOct, minFreq, maxFreq, IREndManualCut=None): """ Calculate the energy level from the room impulsive response. Reference: Christensen, C. L.; Rindel, J. H. APPLYING IN-SITU RECALIBRATION FOR SOUND STRENGTH MEASUREMENTS IN AUDITORIA. :param IR: one channel impulsive response :type IR: ImpulsiveResponse :param nthOct: number of fractions per octave :type nthOct: int :param minFreq: analysis inferior frequency limit :type minFreq: float :param maxFreq: analysis superior frequency limit :type maxFreq: float :return: Analysis object with the calculated parameter :rtype: Analysis """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames is (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # firstChNum = IR.systemSignal.channels.mapping[0] # if not IR.systemSignal.channels[firstChNum].calibCheck: # raise ValueError("'IR' must be a calibrated ImpulsiveResponse") if isinstance(IR, SignalObj): SigObj = cp.copy(IR) elif isinstance(IR, ImpulsiveResponse): SigObj = cp.copy(IR.systemSignal) else: raise TypeError("'IR' must be an ImpulsiveResponse or SignalObj.") # Cutting the IR if IREndManualCut is not None: SigObj.crop(0, IREndManualCut) timeSignal, _ = _circular_time_shift(SigObj.timeSignal[:, 0]) # Bands filtering # hSignal = SignalObj(SigObj.timeSignal[:,0], hSignal = SignalObj(timeSignal, SigObj.lengthDomain, SigObj.samplingRate) hSignal = _filter(signal=hSignal, nthOct=nthOct, minFreq=minFreq, maxFreq=maxFreq) bands = FOF(nthOct=nthOct, freqRange=[minFreq, maxFreq])[:, 1] Lpe = [] for chIndex in range(hSignal.numChannels): Lpe.append(10 * np.log10( np.trapz(y=hSignal.timeSignal[:, chIndex]**2 / (2e-5**2), x=hSignal.timeVector))) LpeAnal = Analysis(anType='mixed', nthOct=nthOct, minBand=float(bands[0]), maxBand=float(bands[-1]), data=Lpe, comment='h**2 energy level') LpeAnal.creation_name = creation_name return LpeAnal
def Lp_ST(sigObjList, nthOct, minFreq, maxFreq, IRManualCut=None): """ Calculate from the provided list of one channel SignalObjs the mean one-third-octave band time-averaged sound pressure level in the test room with the noise source under test in operation, Lp(ST), and the standard deviation, Sm, for the preliminary measurements. Correction for background noise not implemented because of the UFSM reverberation chamber's good isolation. """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames is (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() Leqs = [] for idx, sigObj in enumerate(sigObjList): # if not sigObj.channels[firstChNum].calibCheck: # raise ValueError("SignalObj {} must be calibrated.".format(idx+1)) # Cutting the IR if IRManualCut is not None: sigObj.crop(0, IRManualCut) # Bands filtering hSignal = SignalObj(sigObj.timeSignal[:,0], sigObj.lengthDomain, sigObj.samplingRate) hSignal = _filter(signal=hSignal, nthOct=nthOct, minFreq=minFreq, maxFreq=maxFreq) bands = FOF(nthOct=nthOct, minFreq=minFreq, maxFreq=maxFreq)[:,1] Leq = [] for chIndex in range(hSignal.numChannels): Leq.append( 10*np.log10(np.mean(hSignal.timeSignal[:,chIndex]**2)/ (2e-5**2))) Leq = Analysis(anType='mixed', nthOct=nthOct, minBand=float(bands[0]), maxBand=float(bands[-1]), data=Leq, comment='Leq') Leqs.append(Leq) Leq = 0 for L in Leqs: Leq = L + Leq Lp_ST = Leq / len(sigObjList) Lp_ST.anType = 'mixed' Lp_ST.unit = 'dB' Lp_ST.creation_name = creation_name # Statistics for Lp_ST data = np.vstack([an.data for an in Leqs]) Sm = [] for bandIdx in range(data.shape[1]): summing = 0 for idx in range(data.shape[0]): summing += \ (data[idx, bandIdx] - Lp_ST.data[bandIdx])**2 / (data.shape[0] - 1) Sm.append(summing**(1/2)) Lp_ST.error = Sm Lp_ST.errorLabel = "Standard deviation" return Lp_ST
def random_noise(kind='white', samplingRate=None, fftDegree=None, startMargin=None, stopMargin=None, windowing='hann'): """ Generates a noise of kind White, Pink (TO DO) or Blue (TO DO), with a silence at the beginning and ending of the signal, plus a fade in to avoid abrupt speaker excursioning. All noises have normalized amplitude. White noise is generated using numpy.randn between [[1];[-1]]; Pink noise is still in progress; Blue noise is still in progress; """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # It was done like this because a function default argument is a value # assigned at import time, and PyTTa have a default object that handles # default values for all functions and all classes across all submodules. # In order to it work as expected, the values should be reassigned at # every function call to get updated default values. Otherwise, despite # how the default has it's properties values changed, it won't change # for the function calls. if samplingRate is None: samplingRate = default.samplingRate if fftDegree is None: fftDegree = default.fftDegree if startMargin is None: startMargin = default.startMargin if stopMargin is None: stopMargin = default.stopMargin # [samples] initial silence number of samples stopSamples = round(stopMargin * samplingRate) # [samples] ending silence number of samples startSamples = round(startMargin * samplingRate) # [samples] total silence number of samples marginSamples = startSamples + stopSamples # [samples] full signal number of samples numSamples = 2**fftDegree # [samples] Actual noise number of samples noiseSamples = int(numSamples - marginSamples) if kind.upper() in ['WHITE', 'FLAT']: noiseSignal = np.random.randn(noiseSamples) # elif kind.upper() == 'PINK: # TODO # noiseSignal = np.randn(Nnoise) # noiseSignal = noiseSignal/max(abs(noiseSignal)) # noiseSignal = __do_pink_filtering(noiseSignal) # elif kind.upper() == 'BLUE: # TODO # noiseSignal = np.randn(Nnoise) # noiseSignal = noiseSignal/max(abs(noiseSignal)) # noiseSignal = __do_blue_filtering(noiseSignal) noiseSignal = __do_noise_windowing(noiseSignal, noiseSamples, windowing) noiseSignal = noiseSignal / max(abs(noiseSignal)) noiseSignal = np.concatenate( (np.zeros(int(startSamples)), noiseSignal, np.zeros(int(stopSamples)))) noiseSignal = SignalObj(signalArray=noiseSignal, domain='time', freqMin=default.freqMin, freqMax=default.freqMax, samplingRate=samplingRate) noiseSignal.creation_name = creation_name return noiseSignal
def analyse(obj, *params, bypassLundeby=False, plotLundebyResults=False, suppressWarnings=False, IREndManualCut=None, **kwargs): """ DEPRECATED ---------- Being replaced by class pytta.RoomAnalysis on version 0.1.1. Room analysis over a single SignalObj. Receives an one channel SignalObj or ImpulsiveResponse and calculate the room acoustic parameters especified in the positional input arguments. Calculates reverberation time, definition and clarity. The method for strength factor calculation implies in many input parameters and specific procedures, as the sound source's power estimation. The pytta.roomir app was designed aiming to support this room parameter measurement. For further information check pytta.roomir's and pytta.rooms.strength_factor's docstrings. Input arguments (default), (type): ----------------------------------- * obj (), (SignalObj | ImpulsiveResponse): one channel impulsive response * non-keyworded argument pairs: Pair for 'RT' (reverberation time): - RTdecay (20), (int): Decay interval for RT calculation. e.g. 20 Pair for 'C' (clarity): # TODO - Cparam (50), (int): ... Pair for 'D' (definition): # TODO - Dparam (50), (int): ... * nthOct (), (int): Number of bands per octave; * minFreq (), (int | float): Analysis' inferior frequency limit; * maxFreq (), (int | float): Analysis' superior frequency limit; * bypassLundeby (false), (bool): Bypass lundeby correction * plotLundebyResults (false), (bool): Plot the Lundeby correction parameters; * suppressWarnings (false), (bool): Suppress the warnings from the Lundeby correction; Return (type): -------------- * Analyses (Analysis | list): Analysis object with the calculated parameter or a list of Analyses for more than one parameter. Usage example: >>> myRT = pytta.rooms.analyse(IR, 'RT', 20', 'C', 50, 'D', 80, nthOct=3, minFreq=100, maxFreq=10000) For more tips check the examples folder. """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() warn(DeprecationWarning("Function 'pytta.Analyse' is DEPRECATED and " + "being replaced by the class pytta.RoomAnalysis" + " on version 0.1.1")) if not isinstance(obj, SignalObj) and not isinstance(obj, ImpulsiveResponse): raise TypeError("'obj' must be an one channel SignalObj or" + " ImpulsiveResponse.") if isinstance(obj, ImpulsiveResponse): SigObj = obj.systemSignal else: SigObj = obj if SigObj.numChannels > 1: raise TypeError("'obj' can't contain more than one channel.") # samplingRate = SigObj.samplingRate SigObj = crop_IR(SigObj, IREndManualCut) calcEDC = False result = [] for param in params: if param in ['RT']: # 'C', 'D']: calcEDC = True break if calcEDC: listEDC = cumulative_integration(SigObj, bypassLundeby, plotLundebyResults, suppressWarnings=suppressWarnings, **kwargs) if 'RT' in params: RTdecay = params[params.index('RT')+1] if not isinstance(RTdecay,(int)): RTdecay = 20 nthOct = kwargs['nthOct'] RT = reverberation_time(RTdecay, listEDC) RTtemp = Analysis(anType='RT', nthOct=nthOct, minBand=kwargs['minFreq'], maxBand=kwargs['maxFreq'], data=RT) RTtemp.creation_name = creation_name result.append(RTtemp) # if 'C' in params: # Cparam = params[params.index('C')+1] # if not isinstance(Cparam,(int)): # Cparam = 50 # Ctemp = None # result.append(Ctemp) # if 'D' in params: # Dparam = params[params.index('D')+1] # if not isinstance(Dparam,(int)): # Dparam = 50 # Dtemp = None # result.append(Dtemp) if len(result) == 1: result = result[0] return result
def _extract_stack_iter(frame): for f, lineno in walk_stack(frame): co = f.f_code filename = co.co_filename name = co.co_name yield filename, lineno, name
def dump_all_thread_tracebacks(exclude_thread_ids=None, exclude_self=False, file=sys.stderr): """ :param set[int]|None exclude_thread_ids: set|list of thread.ident to exclude :param bool exclude_self: """ from traceback import print_stack, walk_stack from multiprocessing.pool import worker as mp_worker from multiprocessing.pool import Pool from queue import Queue import threading if not hasattr(sys, "_current_frames"): print( "Does not have sys._current_frames, cannot get thread tracebacks.", file=file) return if exclude_thread_ids is None: exclude_thread_ids = set() exclude_thread_ids = set(exclude_thread_ids) if exclude_self: exclude_thread_ids.add(threading.current_thread().ident) print("", file=file) threads = {t.ident: t for t in threading.enumerate()} for tid, stack in sorted(sys._current_frames().items()): # This is a bug in earlier Python versions. # http://bugs.python.org/issue17094 # Note that this leaves out all threads not created via the threading module. if tid not in threads: continue tags = [] thread = threads.get(tid) if thread: assert isinstance(thread, threading.Thread) if thread is threading.current_thread(): tags += ["current"] if thread is threading.main_thread(): tags += ["main"] tags += [str(thread)] else: tags += ["unknown with id %i" % tid] print("Thread %s:" % ", ".join(tags), file=file) if tid in exclude_thread_ids: print("(Excluded thread.)\n", file=file) continue stack_frames = [f[0] for f in walk_stack(stack)] stack_func_code = [f.f_code for f in stack_frames] if mp_worker.__code__ in stack_func_code: i = stack_func_code.index(mp_worker.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling worker.)\n", file=file) continue if Pool._handle_tasks.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_tasks.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling task handler.)\n", file=file) continue if Pool._handle_workers.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_workers.__code__) if i == 0: # time.sleep is native, thus not on the stack print("(Exclude multiprocessing idling worker handler.)\n", file=file) continue if Pool._handle_results.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_results.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling result handler.)\n", file=file) continue print_stack(stack, file=file) print("", file=file) print("That were all threads.", file=file)
def enum_stacktrace(): return filter(filter_internals, walk_stack(f=None))
def __init__( self, message: str, exc_info: Optional[ExceptionInfoType] = None, traceback: Optional[_traceback.StackSummary] = None, caused_by: Optional['Failure'] = None, sentry: Optional[bool] = True, recoverable: bool = True, fail_guest_request: bool = True, # these are common "details" so we add them as extra keyword arguments with their types scrubbed_command: Optional[List[str]] = None, command_output: Optional[gluetool.utils.ProcessOutput] = None, environment: Optional['Environment'] = None, **details: Any): self.message = message self.exc_info = exc_info self.details = details self.sentry = sentry self.submited_to_sentry: bool = False self.sentry_event_id: Optional[str] = None self.sentry_event_url: Optional[str] = None self.exception: Optional[BaseException] = None self.traceback: Optional[_traceback.StackSummary] = None self.caused_by = caused_by self.recoverable = recoverable # If the failure is irrecoverable, mark the guest request as failed by switching its state # to `ERROR`. This flag gives code chance to avoid this switch - there are places where # we can encounter irrecoverable failures without necessarily failing the whole request, # e.g. when releasing its resources. self.fail_guest_request = fail_guest_request if scrubbed_command: self.details['scrubbed_command'] = scrubbed_command if command_output: self.details['command_output'] = command_output if environment: self.details['environment'] = environment if exc_info: self.exception = exc_info[1] # This is what `traceback.extract_tb` does, but `extract_tb` does not let us save frame locals, # and we would like to see them, at least in Sentry. self.traceback = _traceback.StackSummary.extract( cast(Generator[Tuple[FrameType, int], None, None], _traceback.walk_tb(exc_info[2])), capture_locals=True) self.traceback.reverse() if traceback: self.traceback = traceback if self.traceback is None: # This is what `traceback.extract_stack` does, but `extract_stack` does not let us save frame locals, # and we would like to see them, at least in Sentry. # start with the caller frame - the one creating the Failure f = sys._getframe().f_back self.traceback = _traceback.StackSummary.extract( cast(Generator[Tuple[FrameType, int], None, None], _traceback.walk_stack(f)), capture_locals=True) self.traceback.reverse()
def noise(kind='white', samplingRate=None, fftDegree=None, startMargin=None, stopMargin=None, windowing='hann'): """ Generates a noise of kind White, Pink (TO DO) or Blue (TO DO), with a silence at the beginning and ending of the signal, plus a fade in to avoid abrupt speaker excursioning. All noises have normalized amplitude. White noise is generated using numpy.randn between [[1];[-1]]; # FIXME: This looks incorrect because the signal has normal # distribution, so no limits but an average and standard deviation. Pink noise is still in progress; Blue noise is still in progress; """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames is (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() if samplingRate is None: samplingRate = default.samplingRate if fftDegree is None: fftDegree = default.fftDegree if startMargin is None: startMargin = default.startMargin if stopMargin is None: stopMargin = default.stopMargin # [samples] initial silence number of samples stopSamples = round(stopMargin * samplingRate) # [samples] ending silence number of samples startSamples = round(startMargin * samplingRate) # [samples] total silence number of samples marginSamples = startSamples + stopSamples # [samples] full signal number of samples numSamples = 2**fftDegree # [samples] Actual noise number of samples noiseSamples = int(numSamples - marginSamples) if kind.upper() in ['WHITE', 'FLAT']: noiseSignal = np.random.randn(noiseSamples) # elif kind.upper() == 'PINK: # TODO # noiseSignal = np.randn(Nnoise) # noiseSignal = noiseSignal/max(abs(noiseSignal)) # noiseSignal = __do_pink_filtering(noiseSignal) # elif kind.upper() == 'BLUE: # TODO # noiseSignal = np.randn(Nnoise) # noiseSignal = noiseSignal/max(abs(noiseSignal)) # noiseSignal = __do_blue_filtering(noiseSignal) noiseSignal = __do_noise_windowing(noiseSignal, noiseSamples, windowing) noiseSignal = noiseSignal / max(abs(noiseSignal)) noiseSignal = np.concatenate( (np.zeros(int(startSamples)), noiseSignal, np.zeros(int(stopSamples)))) noiseSignal = SignalObj(signalArray=noiseSignal, domain='time', freqMin=default.freqMin, freqMax=default.freqMax, samplingRate=samplingRate) noiseSignal.creation_name = creation_name return noiseSignal
def G_Lps(IR, nthOct, minFreq, maxFreq): # TODO: Fix documentation format """G_Lps Calculates the recalibration level, for both in-situ and reverberation chamber. Lps is applied for G calculation. During the recalibration: source height and mic heigth must be >= 1 [m], while the distance between source and mic must be <= 1 [m]. The distances must be the same for in-situ and reverberation chamber measurements. Reference: Christensen, C. L.; Rindel, J. H. APPLYING IN-SITU RECALIBRATION FOR SOUND STRENGTH MEASUREMENTS IN AUDITORIA. :param IR: one channel impulsive response :type IR: ImpulsiveResponse :param nthOct: number of fractions per octave :type nthOct: int :param minFreq: analysis inferior frequency limit :type minFreq: float :param maxFreq: analysis superior frequency limit :type maxFreq: float :return: Analysis object with the calculated parameter :rtype: Analysis """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames is (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # firstChNum = IR.systemSignal.channels.mapping[0] # if not IR.systemSignal.channels[firstChNum].calibCheck: # raise ValueError("'IR' must be a calibrated ImpulsiveResponse") if isinstance(IR, SignalObj): SigObj = IR elif isinstance(IR, ImpulsiveResponse): SigObj = IR.systemSignal else: raise TypeError("'IR' must be an ImpulsiveResponse or SignalObj.") # Windowing the IR # dBtoOnSet = 20 # dBIR = 10*np.log10((SigObj.timeSignal[:,0]**2)/((2e-5)**2)) # windowStart = np.where(dBIR > (max(dBIR) - dBtoOnSet))[0][0] broadBandTimeSignal = cp.copy(SigObj.timeSignal[:, 0]) broadBandTimeSignalNoStart, sampleShift = \ _circular_time_shift(broadBandTimeSignal) windowLength = 0.0032 # [s] windowEnd = int(windowLength * SigObj.samplingRate) hSignal = SignalObj( broadBandTimeSignalNoStart[:windowEnd], # hSignal = SignalObj(timeSignal, SigObj.lengthDomain, SigObj.samplingRate) hSignal = _filter(signal=hSignal, nthOct=nthOct, minFreq=minFreq, maxFreq=maxFreq) bands = FOF(nthOct=nthOct, freqRange=[minFreq, maxFreq])[:, 1] Lps = [] for chIndex in range(hSignal.numChannels): timeSignal = cp.copy(hSignal.timeSignal[:, chIndex]) # timeSignalNoStart, sampleShift = _circular_time_shift(timeSignal) # windowLength = 0.0032 # [s] # windowEnd = int(windowLength*SigObj.samplingRate) Lps.append( # 10*np.log10(np.trapz(y=timeSignalNoStart[:windowEnd]**2/(2e-5**2), 10 * np.log10( np.trapz( y=timeSignal**2 / (2e-5**2), # x=hSignal.timeVector[sampleShift:sampleShift+windowEnd]))) x=hSignal.timeVector))) LpsAnal = Analysis(anType='mixed', nthOct=nthOct, minBand=float(bands[0]), maxBand=float(bands[-1]), data=Lps, comment='Source recalibration method IR') LpsAnal.creation_name = creation_name LpsAnal.windowLimits = ((sampleShift) / SigObj.samplingRate, (sampleShift + windowEnd) / SigObj.samplingRate) # Plot IR cutting # fig = plt.figure(figsize=(10, 5)) # ax = fig.add_axes([0.08, 0.15, 0.75, 0.8], polar=False, # projection='rectilinear', xscale='linear') # ax.plot(SigObj.timeVector, 10*np.log10(SigObj.timeSignal**2/2e-5**2)) # ax.axvline(x=(sampleShift)/SigObj.samplingRate, linewidth=4, color='k') # ax.axvline(x=(sampleShift+windowEnd)/SigObj.samplingRate, linewidth=4, color='k') # ax.set_xlim([(sampleShift-100)/SigObj.samplingRate, (sampleShift+windowEnd+100)/SigObj.samplingRate]) return LpsAnal
def f(): summary = traceback.StackSummary.extract(traceback.walk_stack(None)) for fs in summary: print(template.format(fs=fs))
def some_inner(k, v): a = 1 b = 2 return traceback.StackSummary.extract(traceback.walk_stack(None), capture_locals=True, limit=1)
def f(): summary = traceback.StackSummary.extract(traceback.walk_stack(None)) print(''.join(summary.format()))
def test_extract_stack(self): s = traceback.StackSummary.extract(traceback.walk_stack(None)) self.assertIsInstance(s, traceback.StackSummary)
def sweep(freqMin=None, freqMax=None, samplingRate=None, fftDegree=None, startMargin=None, stopMargin=None, method='logarithmic', windowing='hann'): """ Generates a chirp signal defined by the "method" input, windowed, with silence interval at the beggining and end of the signal, plus a hanning fade in and fade out. >>> x = pytta.generate.sweep() >>> x.plot_time() Return a signalObj containing a logarithmic chirp signal from 17.8 Hz to 22050 Hz, with a fade in beginning at 17.8 Hz time instant and ending at the 20 Hz time instant; plus a fade out beginning at 20000 Hz time instant and ending at 22050 Hz time instant. The fade in and the fade out are made with half hanning window. First half for the fade in and last half for the fade out. Different number of points are used for each fade, so the number of time samples during each frequency is respected. Input arguments (default), (type): ------------------------ * freqMin (20), (float) * freqMax (20), (float) * samplingRate (44100), (int) * fftDegree (18), (float) * startMargin (0.3), (float) * stopMargin (0.7), (float) * method (logarithmic'), (string) * windowing ('hann'), (string) """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # It was done like this because a function default argument is a value # assigned at import time, and PyTTa have a default object that handles # default values for all functions and all classes across all submodules. # In order to it work as expected, the values should be reassigned at # every function call to get updated default values. Otherwise, despite # how the default has it's properties values changed, it won't change # for the function calls. if freqMin is None: freqMin = default.freqMin if freqMax is None: freqMax = default.freqMax if samplingRate is None: samplingRate = default.samplingRate if fftDegree is None: fftDegree = default.fftDegree if startMargin is None: startMargin = default.startMargin if stopMargin is None: stopMargin = default.stopMargin # frequency limits [Hz] freqLimits = { 'freqMin': freqMin / (2**(1 / 6)), 'freqMax': min(freqMax * (2**(1 / 6)), samplingRate / 2) } samplingTime = 1 / samplingRate # [s] sampling period stopSamples = stopMargin * samplingRate # [samples] initial silence number of samples startSamples = startMargin * samplingRate # [samples] ending silence number of samples marginSamples = startSamples + stopSamples # [samples] total silence number of samples numSamples = 2**fftDegree # [samples] full signal number of samples sweepSamples = numSamples - marginSamples + 1 # [samples] actual sweep number of samples if sweepSamples < samplingRate / 10: raise Exception('Too small resultant sweep. For such big margins you' + ' must increase your fftDegree.') sweepTime = sweepSamples / samplingRate # [s] sweep's time length timeVecSweep = np.arange(0, sweepTime, samplingTime) # [s] time vector if timeVecSweep.size > sweepSamples: timeVecSweep = timeVecSweep[0:int(sweepSamples)] # adjust length sweep = 0.95 * ss.chirp(timeVecSweep, freqLimits['freqMin'], sweepTime, freqLimits['freqMax'], 'logarithmic', phi=-90) # sweep, time domain sweep = __do_sweep_windowing(sweep, timeVecSweep, freqLimits, freqMin, freqMax, windowing) # fade in and fade out # add initial and ending slices timeSignal = np.concatenate( (np.zeros(int(startSamples)), sweep, np.zeros(int(stopSamples)))) if timeSignal.size != numSamples: timeSignal = timeSignal[0:int(numSamples)] # adjust length # transforms into a pytta signalObj and sets the correct name sweepSignal = SignalObj(signalArray=timeSignal, domain='time', samplingRate=samplingRate, **freqLimits) sweepSignal.creation_name = creation_name return sweepSignal
def colored_noise(color: str or int = 'white', samplingRate: int = None, fftDegree: int = None, numChannels: int = None, startMargin: float = None, stopMargin: float = None, windowing: str = 'hann'): """ Power law noise generator. Based on the algorithm in: Timmer, J. and Koenig, M.: On generating power law noise. Astron. Astrophys. 300, 707-710 (1995) Generate random noise with respect to the `(1/f)**B` rate. `f` stands for frequency and `B` is an integer power. The colors and its spectrum characteristics: * Purple | Differentiated: * +6.02 dB/octave | +20 dB/decade | B = -2; * color: 'purple', 'diff', 'differentiated'; * Blue | Azure: * +3.01 dB/octave | +10 dB/decade | B = -1; * color: 'blue', 'azure' * White | Flat: * +0.00 dB/octave | +0 dB/decade | B = 0; * color: 'white', 'flat'; * Pink | Flicker: * -3.01 dB/octave | -10 dB/decade | B = 1; * color: 'pink', 'flicker', '1/f'; * Red | Brownian: * -6.02 dB/octave | -20 dB/decade | B = 2; * color: 'red', 'brown', 'brownian'; The output signal will have `startMargin` silence at the beginning of the waveform, and `stopMargin` silence at the end. There is a fade-in between the starting silence and the noise itself that occurs during 5% of the total noise duration. @author: Chum4k3r """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # It was done like this because a function default argument is a value # assigned at import time, and PyTTa have a default object that handles # default values for all functions and all classes across all submodules. # In order to it work as expected, the values should be reassigned at # every function call to get updated default values. Otherwise, despite # how the default has it's properties values changed, it won't change # for the function calls. if samplingRate is None: samplingRate = default.samplingRate if fftDegree is None: fftDegree = default.fftDegree if numChannels is None: numChannels = len(default.outChannel) if startMargin is None: startMargin = default.startMargin if stopMargin is None: stopMargin = default.stopMargin # [samples] initial silence number of samples stopSamples = round(stopMargin * samplingRate) # [samples] ending silence number of samples startSamples = round(startMargin * samplingRate) # [samples] total silence number of samples marginSamples = startSamples + stopSamples # [samples] full signal number of samples numSamples = 2**fftDegree # [samples] Actual noise number of samples noiseSamples = int(numSamples - marginSamples) if type(color) == int: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, color, samplingRate) elif type(color) == str: if color.upper() in ['PURPLE', 'DIFF', 'DIFFERENTIATED']: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, -2, samplingRate) elif color.upper() in ['BLUE', 'AZURE']: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, -1, samplingRate) elif color.upper() in ['WHITE', 'FLAT']: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, 0, samplingRate) elif color.upper() in ['PINK', 'FLICKER', '1/F']: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, 1, samplingRate) elif color.upper() in ['RED', 'BROWN', 'BROWNIAN']: noiseSignal = _powerlaw_noise(noiseSamples, numChannels, 2, samplingRate) else: raise ValueError("Unknow noise color.") else: raise TypeError("`color` must be int or str.") noiseSignal = __do_noise_windowing(noiseSignal, noiseSamples, windowing) # noiseSignal = noiseSignal / max(abs(noiseSignal)) noiseSignal = np.concatenate((np.zeros( (int(startSamples), numChannels)), noiseSignal, np.zeros((int(stopSamples), numChannels)))) noiseSignal = SignalObj(signalArray=noiseSignal, domain='time', freqMin=default.freqMin, freqMax=default.freqMax, samplingRate=samplingRate) noiseSignal.creation_name = creation_name return noiseSignal
def sin(Arms=0.5, freq=1000, timeLength=1, phase=2 * np.pi, samplingRate=default.samplingRate, fftDegree=None): """ Generates a sine signal with the traditional parameters plus some PyTTa options. Creation parameters: -------------------- * Arms (float) (optional): The signal's RMS amplitude. >>> Apeak = Arms*sqrt(2); * freq (float) (optional): Nothing to say; * timeLength (float) (optional): Sine timeLength in seconds; * fftDegree (int) (optional); 2**fftDegree signal's number of samples; * phase (float) (optional): Sine phase in radians; * samplingRate (int) (optional): Nothing to say; """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() if fftDegree is not None: timeLength = 2**(fftDegree) / samplingRate t = np.linspace(0, timeLength - (1 / samplingRate), int(samplingRate * timeLength)) sin = Arms * (2**(1 / 2)) * np.sin(2 * np.pi * freq * t + phase) sinSigObj = SignalObj(sin, domain='time', samplingRate=samplingRate, freqMin=default.freqMin, freqMax=default.freqMax) sinSigObj.creation_name = creation_name return sinSigObj
def f(): summary = traceback.StackSummary.extract( traceback.walk_stack(None) ) for fs in summary: print(template.format(fs=fs))
def measurement(kind='playrec', samplingRate=None, freqMin=None, freqMax=None, device=None, inChannels=None, outChannels=None, *args, **kwargs): """ Generates a measurement object of type Recording, Playback and Recording, Transferfunction, with the proper initiation arguments, a sampling rate, frequency limits, audio input and output devices and channels >>> pytta.generate.measurement(kind, [lengthDomain, fftDegree, timeLength, excitation, outputAmplification], samplingRate, freqMin, freqMax, device, inChannels, outChannels, comment) The parameters between brackets are different for each value of the (kind) parameter. >>> msRec = pytta.generate.measurement(kind='rec') >>> msPlayRec = pytta.generate.measurement(kind='playrec') >>> msFRF = pytta.generate.measurement(kind='frf') The input arguments may be different for each measurement kind. Options for (kind='rec'): - lengthDomain: 'time' or 'samples', defines if the recording length will be set by time length, or number of samples; - timeLength: [s] used only if (domain='time'), set the duration of the recording, in seconds; - fftDegree: represents a power of two value that defines the number of samples to be recorded: >>> numSamples = 2**fftDegree - samplingRate: [Hz] sampling frequency of the recording; - freqMin: [Hz] smallest frequency of interest; - freqMax: [Hz] highest frequency of interest; - device: audio I/O device to use for recording; - inChannels: list of active channels to record; - comment: any commentary about the recording. Options for (kind='playrec'): - excitation: object of SignalObj class, used for the playback; - outputAmplification: output gain in dB; - samplingRate: [Hz] sampling frequency of the recording; - freqMin: [Hz] smallest frequency of interest; - freqMax: [Hz] highest frequency of interest; - device: audio I/O device to use for recording; - inChannels: list of active channels to record; - outChannels: list of active channels to send the playback signal, for M channels it is mandatory for the excitation signal to have M columns in the timeSignal parameter. - comment: any commentary about the recording. Options for (kind='frf'): - same as for (kind='playrec'); - regularization: [boolean] option for Kirkeby regularization """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() # Default Parameters if freqMin is None: freqMin = default.freqMin if freqMax is None: freqMax = default.freqMax if samplingRate is None: samplingRate = default.samplingRate if device is None: device = default.device if inChannels is None: inChannels = default.inChannel[:] if outChannels is None: outChannels = default.outChannel[:] # Kind REC if kind in ['rec', 'record', 'recording', 'r']: recordObj = RecMeasure(samplingRate=samplingRate, freqMin=freqMin, freqMax=freqMax, device=device, inChannels=inChannels, **kwargs) if ('lengthDomain' in kwargs) or args: if kwargs.get('lengthDomain') == 'time': recordObj.lengthDomain = 'time' try: recordObj.timeLength = kwargs.get('timeLength') except KeyError: recordObj.timeLength = default.timeLength elif kwargs.get('lengthDomain') == 'samples': recordObj.lengthDomain = 'samples' try: recordObj.fftDegree = kwargs.get('fftDegree') except KeyError: recordObj.fftDegree = default.fftDegree else: recordObj.lengthDomain = 'samples' recordObj.fftDegree = default.fftDegree recordObj.creation_name = creation_name return recordObj # Kind PLAYREC elif kind in ['playrec', 'playbackrecord', 'pr']: if 'outputAmplification' in kwargs: outputAmplification = kwargs.get('outputAmplification') kwargs.pop('outputAmplification', None) else: outputAmplification = 0 if ('excitation' in kwargs.keys()) or args: signalIn = kwargs.get('excitation') or args[0] kwargs.pop('excitation', None) else: signalIn = sweep(samplingRate=samplingRate, freqMin=freqMin, freqMax=freqMax, **kwargs) playRecObj = PlayRecMeasure(excitation=signalIn, outputAmplification=outputAmplification, device=device, inChannels=inChannels, outChannels=outChannels, freqMin=freqMin, freqMax=freqMax, **kwargs) playRecObj.creation_name = creation_name return playRecObj # Kind FRF elif kind in ['tf', 'frf', 'transferfunction', 'freqresponse']: if 'regularization' in kwargs: regularization = kwargs.get('regularization') kwargs.pop('regularization', None) else: regularization = True if 'outputAmplification' in kwargs: outputAmplification = kwargs.get('outputAmplification') kwargs.pop('outputAmplification', None) else: outputAmplification = 0 if ('excitation' in kwargs) or args: signalIn = kwargs.get('excitation') or args[0] kwargs.pop('excitation', None) else: signalIn = sweep(samplingRate=samplingRate, freqMin=freqMin, freqMax=freqMax, **kwargs) frfObj = FRFMeasure(excitation=signalIn, outputAmplification=outputAmplification, device=device, inChannels=inChannels, outChannels=outChannels, freqMin=freqMin, freqMax=freqMax, regularization=regularization, **kwargs) frfObj.creation_name = creation_name return frfObj
def stream(IO='IO', device=None, integration=None, samplingRate=None, inChannels=None, outChannels=None, duration=None, excitation=None, callback=None, *args, **kwargs): """ """ # Code snippet to guarantee that generated object name is # the declared at global scope # for frame, line in traceback.walk_stack(None): for framenline in traceback.walk_stack(None): # varnames = frame.f_code.co_varnames varnames = framenline[0].f_code.co_varnames if varnames == (): break # creation_file, creation_line, creation_function, \ # creation_text = \ extracted_text = \ traceback.extract_stack(framenline[0], 1)[0] # traceback.extract_stack(frame, 1)[0] # creation_name = creation_text.split("=")[0].strip() creation_name = extracted_text[3].split("=")[0].strip() if device is None: device = default.device if integration is None: integration = default.integration if inChannels is None: inChannels = default.inChannel[:] if isinstance(excitation, SignalObj): excit = True excitData = excitation.timeSignal[:] samplingRate = excitation.samplingRate duration = excitation.timeLength outChannels = excitation.channels[:] else: excit = False if samplingRate is None: samplingRate = default.samplingRate if IO in ['I', 'in', 'input']: stream = Streaming(device=device, integration=integration, inChannels=inChannels, duration=duration, callback=callback, samplingRate=samplingRate, *args, **kwargs) elif IO in ['O', 'out', 'output']: if excit: stream = Streaming(device=device, integration=integration, outChannels=outChannels, duration=duration, excitationData=excitData, samplingRate=samplingRate, callback=callback, *args, **kwargs) else: excitation = sweep(samplingRate=samplingRate) outChannels = excitation.channels duration = excitation.timeLength excitData = excitation.timeSignal[:] stream = Streaming(device=device, integration=integration, outChannels=outChannels, duration=duration, excitationData=excitData, samplingRate=samplingRate, callback=callback, *args, **kwargs) elif IO in ['IO', 'in-out', 'input-output']: if excit: stream = Streaming(device=device, integration=integration, inChannels=inChannels, outChannels=outChannels, duration=duration, excitationData=excitData, samplingRate=samplingRate, callback=callback, *args, **kwargs) else: excitation = sweep(samplingRate=samplingRate) outChannels = excitation.channels[:] duration = excitation.timeLength excitData = excitation.timeSignal[:] stream = Streaming(device=device, integration=integration, inChannels=inChannels, outChannels=outChannels, duration=duration, excitationData=excitData, samplingRate=samplingRate, callback=callback, *args, **kwargs) else: raise ValueError("The IO parameter could not identify whether the\ stream will be Input, Output or Input-Output type.") stream.creation_name = creation_name return stream
def some_inner(k, v): a = 1 b = 2 return traceback.StackSummary.extract( traceback.walk_stack(None), capture_locals=True, limit=1)
def f(): summary = traceback.StackSummary.extract( traceback.walk_stack(None) ) print(''.join(summary.format()))
def _get_parent(f): for cf, _ in traceback.walk_stack(f): if cf in _frame_node_dict: return _frame_node_dict[cf]