split midi file for each bar in python - python

I want to divide the MIDI file in python into bars and get the notes in that bars.
So I use music21 library and I can get the notes but I can't split it up by bar.
I want to know what kind of notes are in bar 1 and what are in bar 2.
I hope I can get some help with this problem.Thank you.

In recent versions of music21 (v7+ released after this question was first posted), you can just load the MIDI file and iterate on each measure, using the .measure(num) function and checking if the item returned has any measures in it:
myScore = converter.parse('filename.mid')
i = 1
while (measureStack := myScore.measure(i))[stream.Measure]:
print(len(measureStack[note.Note]))
i += 1
Prior to v7, you'll want to run myScore.makeMeasures(inPlace=True) before running this code. (Before v7, you'll also want to call .recurse().getElementsByClass(XXXX) instead of [XXXX]

Related

MoviePy - getting progress bar values

I am running a python script which converts a video file to a audio clip using moviepy.
def convert(mp3_file,mp4_file):
videoclip = VideoFileClip(mp4_file)
audioclip = videoclip.audio
audioclip.write_audiofile(mp3_file)
audioclip.close()
videoclip.close()
I found out that Moviepy uses a library called Proglog to print a command line progress bar.
How do I get these process completion percentage values?
WARNING: Bruteforce ahead!
It is possible, however, moviepy has no official method to do this.
We can get the progress inside the source code of the module
we need to edit the module code and follow the steps. [This is for ubuntu linux]
Step 1 -
go to the ffmpg_writter.py [usually in /home/anipr/.local/lib/python3.10/site-packages/moviepy/video/io/ffmpeg_writer.py]
Step 2 -
go to line 221 and add calculate the percentage based on duration - get_the_persentage_of_progress = (t/clip.duration)*100
Step - 3
do anything with the variable get_the_persentage_of_progress
however, getting the variable back to our original code is a bit tricky.
here are a few ideas -
write it to a file.txt
insert into database
[let me know in comments if any better idea]

trying to make a video using moviepy

Having a issue with my code. I'm getting a list index out of range index error
import os
import moviepy.video.io.ImageSequenceClip
image_folder= r'C:\Users\Porsche\OneDrive - Imperial College London\Documents\plates'
fps=1
image_files = [image_folder+'/'+img for img in os.listdir(image_folder) if img.endswith(".jpeg")]
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
clip.write_videofile('my_video.mp4')
I'm new to Python and I can't seem to see where the index is and the documentation I found for moviepy was not clear.
the error is on this line
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(image_files, fps=fps)
I just used ImageSequenceClip 5 minutes ago to successfully make a small video so maybe I can assist.
Below are issues related to what I saw in your code and related to problems I had with ImageSequenceClip also. I didn't experience an index error similar to what you've mentioned, but that may be due to your list comprehension line.
A few general suggestions--maybe this will be enough or helpful in other projects you work on:
Careful with your '/' and '\'; keep these uniform to avoid any unwanted issues popping up. I typically use / in all cases for Windows filesystems and it seems to work fine. Also, when manually combining path+filename variables don't forget to include a final '/' at the end of the path variable.
Print out and check the length of the image_files variable you create to make sure you are actually adding the files you wanted and there are no other obvious issues with your list comprehension line.
If you can't locate the issue causing the index error, you can try adding just the folder with the image files only (instead of a list of individual image file locations). In this case, you might need to make a new folder with the files you want included only.
the fps argument was counterintuitive, for me at least. The lower the value, the longer the duration of the individual images in the video.
Finally, the directory you provide to the ImageSequenceClip function will sort the files in alphanumeric order based on the filenames. Keep this in mind as, for example, a1, a2, a11 will be reordered into a1, a11, a2.

Python PiCamera - How do I format the coordinates for the Exif?

I just got my first Raspberry Pi product last week. I got a Raspberry Pi Zero W, and a PiCamera. I created a program (to be ran each day by crontab) that will take a photo, store the photo locally, transfer a copy of the photo to a local server, make a CSV log of the photo, and make an easily readable text daily report. I've gotten almost everything working correctly, but I have one particular issue I can't seem to figure out.
I'm using the Python PiCamera library to capture the photos everyday, and I wanted to set some static GPS data to each photo's EXIF metadata. (The GPS data needs to be static because the Pi is suction cupped to a window and wont be moving for at least a year) The issue I need help with is that I do not know how EXACTLY I need to format my GPS data for PiCamera's exif_tag property. Here are some of the formats I've tried and have not given me appropriate results:
Attempt #1 - Float
camera.exif_tags["GPS.GPSLatitude"] = 41.1027
camera.exif_tags["GPS.GPSLongitude"] = -85.1362
I get this error:
Traceback (most recent call last):
File "main.py", line 13, in <module>
camera.capture(local_path)
File "/usr/lib/python3/dist-packages/picamera/camera.py", line 1418, in capture
encoder.start(output)
File "/usr/lib/python3/dist-packages/picamera/encoders.py", line 1125, in start
self._add_exif_tag(tag, value)
File "/usr/lib/python3/dist-packages/picamera/encoders.py", line 1097, in _add_exif_tag
ct.sizeof(mmal.MMAL_PARAMETER_EXIF_T) + len(tag) + len(value) + 1)
TypeError: object of type 'float' has no len()
Attempt #2 - String
camera.exif_tags["GPS.GPSLatitude"] = "41.1027"
camera.exif_tags["GPS.GPSLongitude"] = "-85.1362"
No error is produced when running this code, however the output data from the exif after the image is captured is still inaccurate:
Latitude |0.040
Longitude |3162715.1775
Follow Up Attempts - Other Strings
# Style 1
camera.exif_tags["GPS.GPSLatitude"] = "(41) (6) (10.711)"
camera.exif_tags["GPS.GPSLongitude"] = "(85) (8) (8.968)"
# This produces
Latitude |1.00
Longitude |1.00
# Style 2
camera.exif_tags["GPS.GPSLatitude"] = "41 6 10.711"
camera.exif_tags["GPS.GPSLongitude"] = "85 8 8.968"
# This produces
Latitude |6.8
Longitude |10.6
# Style 3
camera.exif_tags["GPS.GPSLatitude"] = "41, 6, 10.711"
camera.exif_tags["GPS.GPSLongitude"] = "85, 8, 8.968"
#This produces
Latitude |6.8, 0.014, 1.000
Longitude |10.6, 0.008, 2.141837875
So, in short, can anyone help me by providing me with the means to format my strings? I am at a complete loss. The documentation for PiCamera only lists the different tags but does not explain how to format each of them.
Alright, so after several more test cases, a couple hours of research, and finally posting an issue on the PiCamera GitHub repo I finally figured it out. There is no direct documentation on this particular part of the PiCamera library as stated in my question. But someone on the repo was able to point me to the RaspiStill repo on adding GPS exif data, which is written in C. I've never completely learned C and my C++ skills are a bit rusty, but it gave me an idea. The end result came out to this:
camera.exif_tags["GPS.GPSLatitude"] = "41/1,6/1,9577/1000"
camera.exif_tags["GPS.GPSLongitude"] = "85/1,8/1,10223/1000"
When looking over the RaspiStill repo it got me thinking of how you would use the commands in the terminal to set exif data, so I looked up how to set the coordinates via RaspiStill and found this documentation which gave an example.
RaspiStill Documentation
Some examples of how to represent the data in the form of degrees, minutes, and seconds:
52 = 52 / 1 (52 units)
40.44 = 4044 / 100 (4044 hundredths)
52.97790 = 52977900 / 1000000 (52977900 millionths)
0 = 0/1
This is the source of where I found how to do the above "calculations":
Geotag - Exif Data
Hopefully this can help someone else too.

pdflatex hang after large number of figures

I have a script that generates a number of figures and puts them in the appendix of a report, e.g.
Appendix
********
.. figure:: images/generated/image_1.png
.. figure:: images/generated/image_2.png
.. figure:: images/generated/image_3.png
... etc
It looks like after a large number (~50) of images, my pdflatex command will hang, and point to one of the graphics in my .tex file around here
...
\begin(figure)[htbp]
\centering
\noindent\sphinxincludegraphics{{image_49}.png}
\end{figure}
\begin(figure)[htbp]
\centering
\noindent\sphinxincludegraphics{{image_50}.png} <--- here
\end{figure}
\begin(figure)[htbp]
\centering
\noindent\sphinxincludegraphics{{image_51}.png}
\end{figure}
...
When pdflatex fails I can't really figure out what to make from the console output, I get a number of these lines which seem to be good news
<image_48.png, id=451, 411.939pt x 327.3831pt>
File: image_48.png Graphic file (type png)
<use image_48.png>
Package pdftex.def Info: image_48.png used on input line 1251.
(pdftex.def) Requested size: 411.93797pt x 327.3823pt.
<image_49.png, id=452, 411.939pt x 327.3831pt>
File: image_49.png Graphic file (type png)
<use image_49.png>
Package pdftex.def Info: image_49.png used on input line 1257.
(pdftex.def) Requested size: 411.93797pt x 327.3823pt.
Then after the last successful image (~50) it starts outputting
! Output loop---100 consecutive dead cycles.
\end#float ...loatpenalty <-\#Mii \penalty -\#Miv
\#tempdima \prevdepth \vbo...
l.1258 \end{figure}
I've concluded that your \output is awry; it never does a
\shipout, so I'm shipping \box255 out myself. Next time
increase \maxdeadcycles if you want me to be more patient!
[9
! Undefined control sequence.
\reserved#a ->\#nil
l.1258 \end{figure}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
If all I do is reduce the number of figures, it will run and produce a pdf without issue. Is there a hard limit to the number of images a section can have? Is there somewhere else I can look in the build log to narrow down why this is happening?
This seemed to be a combination of a couple things.
The first symptom was essentially an error caused by too many unprocessed floats. The fix for this was to add the following to the babel element of latex_elements
\usepackage[maxfloats=256]{morefloats}
The second symptom was complaining about Output loop---100 consecutive dead cycles. so the fix was simply to increase the number of cycles
\maxdeadcycles=1000
After these two adjustments, the pdflatex command will finish successfully now, even with a large number of figures.
I had this problem and the above suggestions did not work. I was however able to get it to run just fine by inserting subsections which may or may not compatible with your objectives. The script generates code as follows which is then input into another code snippet to preview the generated images,
( I'm generating svg plots from c++, converting to png, and previewing essentially raw data for selection into later plots that go into an actual document not just a collection of images )
\subsection{svghappy2.tyrosine.png}
\begin{figure}[htbp]
\testplot{svghappy2_tyrosine.png}
\caption{svghappy2.tyrosine.png}
\end{figure}
\subsection{svghappy2.valine.png}
\begin{figure}[htbp]
\testplot{svghappy2_valine.png}
\caption{svghappy2.valine.png}
\end{figure}
As the problem arises from the compiler having hard time to set all the images. Splitting between them would help. As #mike-marchywka noted sections may do the trick, but so would other things, such as \pagebreak or \FloatBarrier from placeins

How to organize a Python GIS-project with multiple analysis steps?

I just started to use ArcPy to analyse geo-data with ArcGIS. The analysis has different steps, which are to be executed one after the other.
Here is some pseudo-code:
import arcpy
# create a masking variable
mask1 = "mask.shp"
# create a list of raster files
files_to_process = ["raster1.tif", "raster2.tif", "raster3.tif"]
# step 1 (e.g. clipping of each raster to study extent)
for index, item in enumerate(files_to_process):
raster_i = "temp/ras_tem_" + str(index) + ".tif"
arcpy.Clip_management(item, '#', raster_i, mask1)
# step 2 (e.g. change projection of raster files)
...
# step 3 (e.g. calculate some statistics for each raster)
...
etc.
This code works amazingly well so far. However, the raster files are big and some steps take quite long to execute (5-60 minutes). Therefore, I would like to execute those steps only if the input raster data changes. From the GIS-workflow point of view, this shouldn't be a problem, because each step saves a physical result on the hard disk which is then used as input by the next step.
I guess if I want to temporarily disable e.g. step 1, I could simply put a # in front of every line of this step. However, in the real analysis, each step might have a lot of lines of code, and I would therefore prefer to outsource the code of each step into a separate file (e.g. "step1.py", "step2.py",...), and then execute each file.
I experimented with execfile(step1.py), but received the error NameError: global name 'files_to_process' is not defined. It seems that the variables defined in the main script are not automatically passed to scripts called by execfile.
I also tried this, but I received the same error as above.
I'm a total Python newbie (as you might have figured out by the misuse of any Python-related expressions), and I would be very thankful for any advice on how to organize such a GIS project.
I think what you want to do is build each step into a function. These functions can be stored in the same script file or in their own module that gets loaded with the import statement (just like arcpy). The pseudo code would be something like this:
#file 1: steps.py
def step1(input_files):
# step 1 code goes here
print 'step 1 complete'
return
def step2(input_files):
# step 2 code goes here
print 'step 2 complete'
return output # optionally return a derivative here
#...and so on
Then in a second file in the same directory, you can import and call the functions passing the rasters as your inputs.
#file 2: analyze.py
import steps
files_to_process = ["raster1.tif", "raster2.tif", "raster3.tif"]
steps.step1(files_to_process)
#steps.step2(files_to_process) # uncomment this when you're ready for step 2
Now you can selectively call different steps of your code and it only requires commenting/excluding one line instead of a whle chunk of code. Hopefully I understood your question correctly.

Categories