adding MIDI chords at specific MetaMessage time - python

I have a MIDI file with marker as meta-messages.
fname = "avm.mid"
mid = MidiFile(fname) # input file of type 0
metas = [m for m in mid.tracks[0] if m.is_meta]
I have stored the meta marker times in the list "chordTimes". The first maker ( chord position) does not start at 0. I make a new MIDI file:
mo = MidiFile(type =1)# output file
track = MidiTrack()
Now I read through my list of desired chords and and add them to a new track to be added to mo.
for i in range(0, len(chords)-1):
chordInfo = chordMidiNotes(chords[i], extraBass= False)
chordNotes = chordInfo[0]
# append to track note on messages
if i != 0:
for note_value in chordNotes: # result has chord notes
track.append(Message('note_on', note=note_value, velocity=100, time=0))
else:
for j,note_value in enumerate(chordNotes): # result has chord notes
if j == 0:
track.append(Message('note_on', note=note_value, velocity=100, time=chordTimes[0]))
else:
track.append(Message('note_on', note=note_value, velocity=100, time=0))
# append to track note off messages
for k,note_value in enumerate(chordNotes): # result has chord notes
if k == 0:
track.append(Message('note_off', note=note_value, velocity=127, time=chordTimes[i+1]))
else:
track.append(Message('note_off', note=note_value, velocity=127, time=0))
# now adding track to output file
mo.tracks.append(mid.tracks[0])
mo.tracks.append(track)
mo.save("songWithChords.mid")
But when I display it, the chords seem to be incorrect and in the wrong position and look much longer ( about 3 times) than the original one. I checked the header chunk of the output:
<meta message time_signature numerator=4 denominator=4 clocks_per_click=24 notated_32nd_notes_per_beat=8 time=0>,
Any help would be greatly appreciated.

Related

OSError: The topology is loaded by filename extension, and the detected ".pd" format is not supported

I'm writing a code to generate features of ligands. Code is:
def parsePDB(self):
top = self.pdb.topology
residues = [str(residue)[:3] for residue in top.residues]
residues_cp = residues.copy()
# number of all groups in the complex except the ligand
LIG_number = residues.index('LIG')
self.residues_indices = [i for i in range(top.n_residues) if i != LIG_number]
# Get the types of atoms in the protein and ligand
self.rec_indices = top.select('protein')
self.lig_indices = top.select('resname LIG')
table, bond = top.to_dataframe()
self.all_ele = table['element']
self.lig_ele = table['element'][self.lig_indices]
H_num = []
for num, i in enumerate(self.all_ele):
if i == 'H':
H_num.append(num)
# Get the serial number of the atom in each residue or group
removes = []
for i in self.residues_indices:
atoms = top.residue(i).atoms
each_atoms = [j.index for j in atoms]
heavy_atoms = [x for x in each_atoms if not x in H_num]
if len(heavy_atoms) == 0:
removes.append(i)
else:
self.atoms_indices.append(heavy_atoms)
if len(removes) != 0:
for i in removes:
self.residues_indices.remove(i)
self.residues = [residues_cp[x] for x in self.residues_indices]
# Get the 3D coordinates for all atoms
self.xyz = self.pdb.xyz[0]
return self
I'm getting this error:
OSError: The topology is loaded by filename extension, and the detected ".pd" format is not supported. Supported topology formats include ".pdb", ".pdb.gz", ".h5", ".lh5", ".prmtop", ".parm7", ".prm7", ".psf", ".mol2", ".hoomdxml", ".gro", ".arc", ".hdf5" and ".gsd".
Can anyone please suggest me how to resolve this issue? Thanks

Fastest way to search for *any* number in string w/o Regex in python?

I am a relatively new developer and I have an issue where I am trying to search a string for a specific pattern that may contain a number at a specific position in a single line of a text file.
the method that I am currently writing ingests a single line from that trace file and will need to look for a match against a dictionary of known patterns.
Now, I have heard from my friends who are actual developers of python programs that Regex is actually a relatively slow and inefficient way to perform this sort of operation. But given the nature of my issue i cant think of a way to do it without them.
The process that I am developing will run over nearly 10,000 text files with 200k+ lines each.
Can anyone think of a faster way to do this?
def firm_parser(line):
RgxFrm_PX={
"CycleCount":{
"ptrn":re.search(re.compile(r"P\d{1}RV"),line),
"desc":"Request cycle counter",
"deet":""},
"LastAdjustDate":{
"ptrn":re.search(re.compile(r"P\d{1}RJ"),line),
"desc":"Request adjustment date and status",
"deet":""},
"ChanTemp":{
"prtn":re.search(re.compile(r"P\d{1}RM"),line),
"desc":"Request pipetting channel temperature",
"deet":""}
}
for key,value in RgxFrm_PX:
if value["prtn"]:
print(f"{value["desc"]} {line}")
Wow, I gave it a try, not expecting a bog difference between the regex and the no-regex method, and dang was I surprised!
Here's my version of the function, without regex:
def firm_parserV2(line):
pattern_found = False
matches = []
lineCpy = line
while 1:
idx = lineCpy.find('P')
if idx < 0: break
lineCpy = lineCpy[idx+1:]
if not lineCpy[0].isnumeric():
continue
matches.append([
lineCpy[1:3], # The 2 letters
int(lineCpy[0]) # The number
])
for letters, number in matches:
if letters == 'RV':
message = "Request cycle counter"
elif letters == 'RJ':
message = "Request adjustment date and status"
elif letters == 'RM':
message = "Request pipetting channel temperature"
print(message, line)
I compared the times for a small line (P4RJasd), and here are the results:
+------------------------------+------------------------+
| Function | Time |
+------------------------------+------------------------+
| Original | .003547472953796386 ms |
+------------------------------+------------------------+
| Original with rx compilation | .002606389522552490 ms |
| outside the function | |
+------------------------------+------------------------+
| New version | .000612576007843017 ms |
+------------------------------+------------------------+
Here's the full code I used to compare the 3 functions:
import re
import re
import time
import random
def firm_parser(line):
RgxFrm_PX={
"CycleCount":{
"prtn":re.search(re.compile(r"P\d{1}RV"),line),
"desc":"Request cycle counter",
"deet":""},
"LastAdjustDate":{
"prtn":re.search(re.compile(r"P\d{1}RJ"),line),
"desc":"Request adjustment date and status",
"deet":""},
"ChanTemp":{
"prtn":re.search(re.compile(r"P\d{1}RM"),line),
"desc":"Request pipetting channel temperature",
"deet":""}
}
for key,value in RgxFrm_PX.items():
if value["prtn"]:
pass
# print(f"{value['desc']} {line}")
rx_rv = re.compile(r"P\dRV")
rx_rj = re.compile(r"P\dRJ")
rx_rm = re.compile(r"P\dRM")
def firm_parser_no_rx(line):
RgxFrm_PX={
"CycleCount":{
"prtn":re.search(rx_rv, line),
"desc":"Request cycle counter",
"deet":""},
"LastAdjustDate":{
"prtn":re.search(rx_rj, line),
"desc":"Request adjustment date and status",
"deet":""},
"ChanTemp":{
"prtn":re.search(rx_rm, line),
"desc":"Request pipetting channel temperature",
"deet":""}
}
for key,value in RgxFrm_PX.items():
if value["prtn"]:
pass
# print(f"{value['desc']} {line}")
def firm_parserV2(line):
pattern_found = False
matches = []
lineCpy = line
while 1:
idx = lineCpy.find('P')
if idx < 0: break
lineCpy = lineCpy[idx+1:]
if not lineCpy[0].isnumeric():
continue
matches.append([
lineCpy[1:3], # The 2 letters
int(lineCpy[0]) # The number
])
for letters, number in matches:
if letters == 'RV':
message = "Request cycle counter"
elif letters == 'RJ':
message = "Request adjustment date and status"
elif letters == 'RM':
message = "Request pipetting channel temperature"
# print(message, line)
loop_nb = 100000
test_string = 'P4RJasd'
funcs = [
firm_parser,
firm_parser_no_rx,
firm_parserV2
]
times = {}
for func in funcs: times[func.__name__] = 0
for i in range(loop_nb):
# Scrambling the array...
funcs = sorted(funcs, key = lambda x: random.random() )
for func in funcs:
start = time.time()
func(test_string)
end = time.time()
times[func.__name__] += (end - start)
for func, time in times.items():
print(func + '\t', time / loop_nb)

Changing Image.Grab.grab(value) without retyping

A list helped me make a loop which grabs a part of the screen and compare it to a existing RGB value. Final code is in final edit. Full learnprocess is shown below.
I'm new to coding in general. I am using pixels do verify RGB value of a pixel which declares position of player. But in stead of re-typing location = ImageGrab.grab(position) can I change the position?
seat0 = (658,848,660,850) #btn
seat1 = (428,816,429,817) #co
seat2 = (406,700,407,701) #hj
seat3 = (546,653,547,654) #lj
seat4 = (798,705,799,706) #bb
seat5 = (769,816,770,817) #sb
btnpos = ImageGrab.grab(seat0)
position = btnpos.load()
btn = (251,0,8)
if position[0,0] == btn:
print('Button')
elif ????
So I want to change seat0 (in imagegrab) to seat1 without re-typing the code. Thanks for the help
EDIT1: So I tried Marks suggestion, not sure what I'm doing wrong.
positie = ["(658,848,660,850)","(428,816,430,818)","(406,700,408,702)","(546,653,548,655)","(798,705,799,706)","(769,816,770,817)"]
btn = (251,0,8)
btnpos = ImageGrab.grab(positie[0])
btncheck = btnpos.load()
btn [0,0] not in positie[0]
I get "ValueError: too many values to unpack (expected 4)"
I am trying to RGB value of positie[0] and it has to match btn. if it doesn't match to btn then it has to check positie[1], until it returns true.
Edit2:
Thanks so far Mark. I am so bad at loops.
positie = [(658,848,660,850),(428,816,430,818),(406,700,408,702),(546,653,548,655),(798,705,799,706),(769,816,770,817)]
btn = (251,0,8)
btnpos = ImageGrab.grab(positie[0])
btncheck = btnpos.load()
for x in positie:
#btncheck = btnpos.load()
if btncheck[0,0] ==btn:
print("positie is BTN")
else:
btnpos = (positie[++1])
print(btnpos)
how do I change btnpos with adding up instead of re-typing everything?
So it's supposed to grab first item in list and compare it to btn. If it's correct it can break, if it's wrong it has to compare btn with second item in list.
If true it gives me the position. If false:
Now it prints list[1] six times.
Thank you for your patience
FINAL EDIT: Thank you Mark.
positie = [(658,848,660,850),(428,816,430,818),(406,700,408,702),(546,653,548,655),(798,705,799,706),(769,816,770,817)]
btn = (251,0,8)
counter = 0
max_index = len(positie) - 1
while counter <= max_index:
btnpos = ImageGrab.grab(positie[counter])
btncheck = btnpos.load()
if btncheck[0,0] == btn:
print("Positie")
break
else:
print("controleert de volgende")
counter = counter + 1

While loop incrementer not functioning properly

Right now, my code is correctly spitting out the first game (identified by start_id) in games. I am trying to increment in the bottom two lines, but the while loop doesn't seem to read the fact that I'm incrementing. So the input of this with start_id 800 and end_id 802 is just the information from 800, for some reason.
Am I using the incrementers correctly? Should I be initializing one of i or start_id elsewhere?
games = console(start_id, end_id)
final_output = []
while start_id < (end_id + 1):
single_game = []
i = 0
game_id = games[i][0]
time_entries = games[i][1][2][0]
play_entries = games[i][1][2][1]
score_entries = games[i][1][2][2]
team_entries = games[i][1][2][3]
bovada = games[i][1][0][0][0]
at_capacity = games[i][1][0][1]
idisagree_yetrespect_thatcall = games[i][1][0][2][0]
imsailingaway = games[i][1][1][0][0]
homeiswheretheheartis = games[i][1][1][1][0]
zipper = zip(time_entries, play_entries, score_entries, team_entries)
for play_by_play in zipper:
single_game.append(game_id)
single_game.append(play_by_play)
single_game.append(bovada)
single_game.append(at_capacity)
single_game.append(idisagree_yetrespect_thatcall)
single_game.append(imsailingaway)
single_game.append(homeiswheretheheartis)
start_id += 1
i += 1
final_output.append(single_game)
return final_output
Your problem is that you initialize the increment-er i inside the while loop so every time your loop iterates i is reset to zero.
Try changing it to:
i = 0
while start_id < (end_id + 1):
...

object of type '_Task' has no len() error

I am using the parallel programming module for python I have a function that returns me an array but when I print the variable that contain the value of the function parallelized returns me "pp._Task object at 0x04696510" and not the value of the matrix.
Here is the code:
from __future__ import print_function
import scipy, pylab
from scipy.io.wavfile import read
import sys
import peakpicker as pea
import pp
import fingerprint as fhash
import matplotlib
import numpy as np
import tdft
import subprocess
import time
if __name__ == '__main__':
start=time.time()
#Peak picking dimensions
f_dim1 = 30
t_dim1 = 80
f_dim2 = 10
t_dim2 = 20
percentile = 80
base = 100 # lowest frequency bin used (peaks below are too common/not as useful for identification)
high_peak_threshold = 75
low_peak_threshold = 60
#TDFT parameters
windowsize = 0.008 #set the window size (0.008s = 64 samples)
windowshift = 0.004 #set the window shift (0.004s = 32 samples)
fftsize = 1024 #set the fft size (if srate = 8000, 1024 --> 513 freq. bins separated by 7.797 Hz from 0 to 4000Hz)
#Hash parameters
delay_time = 250 # 250*0.004 = 1 second#200
delta_time = 250*3 # 750*0.004 = 3 seconds#300
delta_freq = 128 # 128*7.797Hz = approx 1000Hz#80
#Time pair parameters
TPdelta_freq = 4
TPdelta_time = 2
#Cargando datos almacenados
database=np.loadtxt('database.dat')
songnames=np.loadtxt('songnames.dat', dtype=str, delimiter='\t')
separator = '.'
print('Please enter an audio sample file to identify: ')
userinput = raw_input('---> ')
subprocess.call(['ffmpeg','-y','-i',userinput, '-ac', '1','-ar', '8k', 'filesample.wav'])
sample = read('filesample.wav')
userinput = userinput.split(separator,1)[0]
print('Analyzing the audio sample: '+str(userinput))
srate = sample[0] #sample rate in samples/second
audio = sample[1] #audio data
spectrogram = tdft.tdft(audio, srate, windowsize, windowshift, fftsize)
mytime = spectrogram.shape[0]
freq = spectrogram.shape[1]
print('The size of the spectrogram is time: '+str(mytime)+' and freq: '+str(freq))
threshold = pea.find_thres(spectrogram, percentile, base)
peaks = pea.peak_pick(spectrogram,f_dim1,t_dim1,f_dim2,t_dim2,threshold,base)
print('The initial number of peaks is:'+str(len(peaks)))
peaks = pea.reduce_peaks(peaks, fftsize, high_peak_threshold, low_peak_threshold)
print('The reduced number of peaks is:'+str(len(peaks)))
#Store information for the spectrogram graph
samplePeaks = peaks
sampleSpectro = spectrogram
hashSample = fhash.hashSamplePeaks(peaks,delay_time,delta_time,delta_freq)
print('The dimensions of the hash matrix of the sample: '+str(hashSample.shape))
# tuple of all parallel python servers to connect with
ppservers = ()
#ppservers = ("10.0.0.1",)
if len(sys.argv) > 1:
ncpus = int(sys.argv[1])
# Creates jobserver with ncpus workers
job_server = pp.Server(ncpus, ppservers=ppservers)
else:
# Creates jobserver with automatically detected number of workers
job_server = pp.Server(ppservers=ppservers)
print ("Starting pp with", job_server.get_ncpus(), "workers")
print('Attempting to identify the sample audio clip.')
Here I call the function in fingerprint, the commented line worked, but when I try parallelize don't work:
timepairs = job_server.submit(fhash.findTimePairs, (database, hashSample, TPdelta_freq, TPdelta_time, ))
# timepairs = fhash.findTimePairs(database, hashSample, TPdelta_freq, TPdelta_time)
print (timepairs)
#Compute number of matches by song id to determine a match
numSongs = len(songnames)
songbins= np.zeros(numSongs)
numOffsets = len(timepairs)
offsets = np.zeros(numOffsets)
index = 0
for i in timepairs:
offsets[index]=i[0]-i[1]
index = index+1
songbins[i[2]] += 1
# Identify the song
#orderarray=np.column_stack((songbins,songnames))
#orderarray=orderarray[np.lexsort((songnames,songbins))]
q3=np.percentile(songbins, 75)
q1=np.percentile(songbins, 25)
j=0
for i in songbins:
if i>(q3+(3*(q3-q1))):
print("Result-> "+str(i)+":"+songnames[j])
j+=1
end=time.time()
print('Tiempo: '+str(end-start)+' s')
print("Time elapsed: ", +time.time() - start, "s")
fig3 = pylab.figure(1003)
ax = fig3.add_subplot(111)
ind = np.arange(numSongs)
width = 0.35
rects1 = ax.bar(ind,songbins,width,color='blue',align='center')
ax.set_ylabel('Number of Matches')
ax.set_xticks(ind)
xtickNames = ax.set_xticklabels(songnames)
matplotlib.pyplot.setp(xtickNames)
pylab.title('Song Identification')
fig3.show()
pylab.show()
print('The sample song is: '+str(songnames[np.argmax(songbins)]))
The function in fingerprint that I try to parallelize is:
def findTimePairs(hash_database,sample_hash,deltaTime,deltaFreq):
"Find the matching pairs between sample audio file and the songs in the database"
timePairs = []
for i in sample_hash:
for j in hash_database:
if(i[0] > (j[0]-deltaFreq) and i[0] < (j[0] + deltaFreq)):
if(i[1] > (j[1]-deltaFreq) and i[1] < (j[1] + deltaFreq)):
if(i[2] > (j[2]-deltaTime) and i[2] < (j[2] + deltaTime)):
timePairs.append((j[3],i[3],j[4]))
else:
continue
else:
continue
else:
continue
return timePairs
The complete error is:
Traceback (most recent call last):
File "analisisPrueba.py", line 93, in <module>
numOffsets = len(timepairs)
TypeError: object of type '_Task' has no len()
The submit() method submits a task to the server. What you get back is a reference to the task, not its result. (How could it return its result? submit() returns before any of that work has been done!) You should instead provide a callback function to receive the results. For example, timepairs.append is a function that will take the result and append it to the list timepairs.
timepairs = []
job_server.submit(fhash.findTimePairs, (database, hashSample, TPdelta_freq, TPdelta_time, ), callback=timepairs.append)
(Each findTimePairs call should calculate one result, in case that isn't obvious, and you should submit multiple tasks. Otherwise you're invoking all the machinery of Parallel Python for no reason. And make sure you call job_server.wait() to wait for all the tasks to finish before trying to do anything with your results. In short, read the documentation and some example scripts and make sure you understand how it works.)

Categories