Saturday, December 29, 2018

Apple Health with Python

For about four years I have been storing my weight in the Apple Health app. At the same time, I am almost always carrying my phone so it has been recording my number of steps for at least as long. As Python seems to be a hot topic at the moment, I thought I would try using it to look for correlations between my weight and number of steps.

The whole project would have been way easier in Excel, but it seemed a good way to learn plotting and mathematics in Python.

First I plotted my weight and number of steps:
The weight plot definitely supports the hypothesis that it is easy to lose weight in the short term, and almost impossible over a five year period. I managed to drop fast when I first started recording but then slowly gained it all back and then some. The steps are more opaque. At first glance they don't say much.

So I tried plotting steps versus weight for the days where I have both sets of data. The X axis is how many steps I took that day, and the Y axis is what I weighed that morning:
Better, this shows that when I am above 190lbs I rarely walk more than 10,000 steps, but it is still an amorphous blob with a whole bunch of noise.

Some of the noise can be removed by instead plotting monthly averages. For every 30 day period in the dataset I averaged my steps and averaged by weight:
Again an amorphous blob, but  it does show that when I walk a lot I am more likely to be low weight and when I am heavy I am more likely to not walk much.

That seemed like it missed an important detail though, am I 190 pounds and dropping fast because I walk so much? or am I 180 pounds and gaining weight fast? That problem can be removed by instead looking at weight gain. So I averaged my number of steps for a 30 day period, then compared my weight in that 30 day period to my weight in the previous 30 day period:


 There is still a lot of noise, but when I lose more than two pounds in a month I always am walking more than 6,500 steps, and when I gain more than a pound in a week I am always walking less than 7,000 steps.

The code to do this simple analysis started with trying to get the data out of the export.xml file which apple provides. This was easy enough in excel, but I made it a point to use python. Eventually I came up with the following script which pulls all the weight and steps from the file:
import xml.etree.ElementTree
# This file location will need to be edited to match where the file is.
xDoc = xml.etree.ElementTree.parse(
        'E:/My Documents/Python files/export/apple_health_data/export.xml')

items = list(xDoc.getroot()) # Convert the XML items to a list

step_data = []

# Searches for steps in the XML file.
item_type_identifier='HKQuantityTypeIdentifierStepCount' # Desired data type
for i,item in enumerate(items):
    if 'type' in item.attrib and item.attrib['type'] == item_type_identifier:
        # Attributes to extract from the current item
        step_data.append((item.attrib['type'],
                         item.attrib['endDate'],
                         item.attrib['value']))

weight_data = []
# Searches for weights in the XML file
item_type_identifier='HKQuantityTypeIdentifierBodyMass'
for i,item in enumerate(items):
    if 'type' in item.attrib and item.attrib['type'] == item_type_identifier:
        # Attributes to extract from the current item
        weight_data.append((item.attrib['type'],
                         item.attrib['endDate'],
                         item.attrib['value']))


file_location = \
    'E:/My Documents/Python files/export/apple_health_data/Extract.csv'
file = open(file_location, 'w')

# Writes the list to a csv file by putting a , after every line and a \n at the
# end of a row.
i= 0
for i in range(len(step_data)):
    file.write(str(step_data[i][0])+',')
    file.write(str(step_data[i][1])+',')
    file.write(str(step_data[i][2])+',')
    file.write(str('\n'))
    i = i + 1

i= 0
for i in range(len(weight_data)):
    file.write(str(weight_data[i][0])+',')
    file.write(str(weight_data[i][1])+',')
    file.write(str(weight_data[i][2])+',')
    file.write(str('\n'))
    i = i + 1
      
file.close()
I could have just used the data directly, but I chose to divide this up into three scripts. Now that I have all the data in a csv file it is necessary to do some basic analysis on it to make the plots. The averaging and summing necessary was done in a second script which imports the data from the previous script and again saves to csv:

import csv
import pandas as pd
import datetime

file_location = \
    'E:/My Documents/Python files/export/apple_health_data/Extract.csv'
   
weights = []
weight = []

# This pulls the weights data out of the csv file and puts it into the object
# called weights
with open(file_location) as csvfile:
    readCSV = csv.reader(csvfile, delimiter=',')

    for row in readCSV:
        if row[0] == 'HKQuantityTypeIdentifierBodyMass':

            pounds = float(row[2])
           
            date_string = row[1].split()[0]
            year_int = int(date_string.split('-')[0])
            month_int = int(date_string.split('-')[1])
            day_int = int(date_string.split('-')[2])

            date = datetime.date(year_int, month_int, day_int)
           
            weight = [date, pounds]
            weights.append(weight)


step_counts = []
step_count = []
# This pulls the steps data out of the csv file and puts it into the object
# called step_counts
with open(file_location) as csvfile:
    readCSV = csv.reader(csvfile, delimiter=',')

    for row in readCSV:
        if row[0] == 'HKQuantityTypeIdentifierStepCount':

            steps = int(row[2])           
            date_string = row[1].split()[0]
            year_int = int(date_string.split('-')[0])
            month_int = int(date_string.split('-')[1])
            day_int = int(date_string.split('-')[2])
            date = datetime.date(year_int, month_int, day_int)
           
            step_count = [date, steps]
            step_counts.append(step_count)
           
# The steps from Apple come in smaller batches than make sense for this analysis
# Therefore I added up all the steps on any particular day and put it in the
# object daily_steps
summed_steps = []
daily_steps = 0
for entry in step_counts:
    if entry[0] == date:
        daily_steps += int(entry[1])
    else:
        days_steps = [date, daily_steps]
        summed_steps.append(days_steps)
        date = entry[0]
        daily_steps = int(entry[1])

# The weights and steps were moved from a list to a dataframe for ease of some
# of the later anaylsis
weights_data_frame=pd.DataFrame(weights,columns=['date', 'weight'])
steps_data_frame = pd.DataFrame(summed_steps,columns=['date','steps'])

# The weights and steps were combined into one dataframe.
combined_data = steps_data_frame.merge(weights_data_frame, how='outer')

# In case any data is out of order it is sorted
combined_data = combined_data.sort_values(by=['date'])

# Calculates the 7 day average weight.
weekly_average_weight = combined_data["weight"].rolling(min_periods=1,
                                                     center=True,
                                                     window=7).mean()
weekly_average_weight = weekly_average_weight.to_frame('weekly average weight')
combined_data = combined_data.join(weekly_average_weight)


# Calculates the 7 day average steps.
weekly_average_steps = combined_data["steps"].rolling(min_periods=1,
                                                    center=True,
                                                    window=7).mean()   
weekly_average_steps = weekly_average_steps.to_frame('weekly average steps')
combined_data = combined_data.join(weekly_average_steps)

# Calculates the 30 day average weight.
monthly_average_weight = combined_data["weight"].rolling(min_periods=1,
                                                     center=True,
                                                     window=30).mean()
monthly_average_weight = monthly_average_weight.to_frame(
                                                'monthly average weight')
combined_data = combined_data.join(monthly_average_weight)


# Calculates the 30 day average steps.
monthly_average_steps = combined_data["steps"].rolling(min_periods=1,
                                                    center=True,
                                                    window=30).mean()   
monthly_average_steps = monthly_average_steps.to_frame('monthly average steps')
combined_data = combined_data.join(monthly_average_steps)


# Compares the average weight to the average weight the week before to look
#for a gain.
i = 0
weekly_gain = []
for i in range(len(combined_data)-4):
    if combined_data.iloc[i+4][3] and combined_data.iloc[i-3][3] \
        and i +4< len(combined_data) and i-4>=0:
            gain = combined_data.iloc[i+4][3] - combined_data.iloc[i-3][3]

            dated_gain = [combined_data.iloc[i][0], gain]
            weekly_gain.append(dated_gain)
            i += 1

# Puts the gain into a dataframe
weekly_gain = pd.DataFrame(weekly_gain,columns=['date','weekly weight gain'])

# Merges the dataframe
combined_data = combined_data.merge(weekly_gain, how='outer')

# Compares the average weight to the average weight the month before to look
# for a gain.
i = 0
monthly_gain = []
for i in range(len(combined_data)-30):
    if combined_data.iloc[i+30][5] and combined_data.iloc[i-30][5] \
        and i +15< len(combined_data) and i-30>=0:
            gain = combined_data.iloc[i][5] - combined_data.iloc[i-30][5]
            print(combined_data.iloc[i])
            date_1 = combined_data.iloc[i][0]
           
            dated_gain = [date_1, gain]
            print(dated_gain)
            monthly_gain.append(dated_gain)
            i += 1
# Puts the gain into a dataframe
monthly_gain = pd.DataFrame(monthly_gain,columns=['date','monthly weight gain'])
print(monthly_gain)
# Merges the dataframe
combined_data = combined_data.merge(monthly_gain, how='outer')


print(combined_data)

combined_data.to_csv("output.csv")
Finally I had to make a bunch of plots out of the data which was stored to the csv. This was done in a third script which imported the formatted data from the second script.

import matplotlib
import matplotlib.pyplot as plt
import pandas as pd

# Imports the csv, will need to change file path to match the location.
file_path = 'E:/My Documents/Python files/export/apple_health_data/output.csv'

# Puts the imported data into a dataframe
combined_data = pd.read_csv(file_path, index_col=0)
combined_data['date'] = pd.to_datetime(combined_data['date'])

# Start of a plot of date versus monthly average steps, first line defines
# which values are plotted against each other.

plt.plot_date(combined_data['date'], combined_data['monthly average steps'])

# Rotates the labels since dates get long otherwise.
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)

# Labels the y axis, x axis not named since dates seem obvious.
plt.ylabel('Average Steps in 30 Day Period')

# The plot is made larger then saved.
fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('monthly_average_steps.png', dpi=100)

# Marks the end of one plot. 
plt.figure()

# Start of second plot.
plt.plot_date(combined_data['date'], combined_data['monthly average weight'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)

plt.ylabel('Average Weight in 30 Day Period')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('monthly_average_weight.png', dpi=100)

plt.figure()

# Start of third plot, this one is a bit different since it is a scatterplot
# rather than a date plot.
plt.scatter(combined_data['monthly average steps'], combined_data['weight'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)
plt.xlabel('Average Steps in 30 Day Period')
plt.ylabel('weight')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('monthly_average_steps_versus_weight.png', dpi=100)

plt.figure()

# Start of fourth plot
plt.scatter(combined_data['monthly average steps'], combined_data['monthly weight gain'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)
plt.xlabel('Average Steps in 30 Day Period')
plt.ylabel('Weight Gain Compared to Previous 30 Day Period')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('monthly_average_steps_versus_weight_gain.png', dpi=100)

plt.figure()

# Start of fifth plot
plt.scatter(combined_data['monthly average steps'], combined_data['monthly average weight'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)
plt.xlabel('Average Steps in 30 Day Period')
plt.ylabel('Monthly Average Weight')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('monthly_average_steps_versus_monthly_average_weight.png', dpi=100)

plt.figure()

# Start of sixth plot
plt.plot_date(combined_data['date'], combined_data['steps'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)

plt.ylabel('daily steps')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('steps.png', dpi=100)

plt.figure()

# Start of seventh plot
plt.plot_date(combined_data['date'], combined_data['weight'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)

plt.ylabel('daily weight')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('weight.png', dpi=100)

plt.figure()

# Start of eight plot
plt.scatter(combined_data['steps'], combined_data['weight'])
plt.setp(plt.gca().xaxis.get_majorticklabels(),rotation=90,)
plt.xlabel('Steps')
plt.ylabel('Weight')

fig = matplotlib.pyplot.gcf()
fig.set_size_inches(12, 8)
fig.savefig('steps_versus_weight.png', dpi=100)

plt.figure()







Sunday, November 25, 2018

For years I have been considering getting an underwater case for my camera and starting to make more underwater iNaturalist observations. I made a few freediving with a GoPro but that camera wasn't really designed for macro shots. Getting a waterproof housing for my real camera terrifies me as I have heard too many stories of wrecked.

So hearing that someone I know bought an underwater drone definitely caught my attention.

The Power Vision PowerRay they bought can go a hundred feet down and stay down two hours. This certainly does seem a step up from freediving for a few seconds to take a few rapid photos. Compared to real scuba diving with a dive housing it isn't quite there, but it is certainly safer and less trouble and should be cheaper. Launching a ROV from a kayak seems much more practical than SCUBA diving from the same small vessels.

The Open ROV Trident however can go to 100 meters. Now we are starting to talk, that depth can certainly be done with SCUBA, but past 50 meters SCUBA starts getting pretty specialized. That means there must be some opportunity to find interesting creatures which haven't been all that well documented.

Then comes the Titan ROV which should start shipping any day. This drone reports a 150 meter maximum depth and 4 hour battery life. While it isn't exactly cheap, at around $3,000 this is certainly the lowest cost way to depths from 100-150 meters. It must be possible to track down creatures at that depth not only not posted to iNaturalist, but almost unstudied. Also, at the rate these drones seem to be improving within five years the cost of entry should be even more reasonable.

Too bad the last thing I need is another expensive hobby.

Saturday, October 27, 2018

Globe Flash V3

I have been using the globe flash macro diffuser I made for the past six months. For close in macro images it really proved amazing. However it had a couple annoyances which I finally decided to address:
  •  It had a paper towel on top of it and wouldn't work without it. That I stuck through six months of a camera that ugly is a good sign of how good of images it produced but it did feel silly. 
  • It was useless beyond about two feet. At these distances the images got really hazy. This is an issue it actually shared with the Sony Twin Flash, and Sigma Ring Flash. Light from the flash would interfere with the image since they don't work with a lens hood.
  • It was incompatible with Raynox macro filters. With these on a macro lens you can get about the best magnification which is usable in the field. 
  • Reflections look a bit funny on some reflective subjects because you can clearly see circular shape of the lens. 
  • It does not work with a lens cap.
Two tweaks fixed both issues. First, the size of the globe was increased to 12 inches. This means it is large enough to completely cover the flash from the perspective of the subject. Second was connecting the globe to a lens hood which blocked the light which was making images hazy.




The image quality for 1X macro is about the same as the previous version but without the previous issues.

 

To build it, I used the following materials:
The steps were pretty simple, although with the tools I had rather time consuming. Simply cut a hole in the acrylic disc for the lens to look through (I used a Dremmel), epoxy the disc to the lens hood, then epoxy the disc to the globe. Then epoxy the globe to the acrylic disc and cut the globe to shape(I used a hack saw). Since polyethylene is notoriously difficult to bond, I briefly. put it in a flame before making the connection.



Thus far this setup has been quite effective. I am a bit worried about the epoxy bond, it seems less sturdy than it was to the previous acrylic globe, but the last one survived six months of abuse so I expect this one will do alright. 

Sunday, April 1, 2018

Globe Flash V2

Before getting into technical details, let me show three photos. All three are with the same camera and lens but were taken using different flashes:

The first uses a Sigma Ring Flash:


The second uses a Sony Twin Flash:
 

The third uses my latest DIY globe flash:

I chose ants because they move so fast they are really difficult to photograph without a flash you typically end up with a blurry mess. All three flashes do a reasonable job of stopping motion and at least making clear it is an ant. There is a real quality improvement from better diffusion though.

The Sigma flash always had a real problem with too little diffusion. Odd hot spots and dark spots really retract from the quality. It calls itself a ring flash, but due to lack of diffusion it is more of a twin flash with two fixed light sources.

The Sony flash was a solid flash, for $750 it better be! Still, even it ended up with some hot spots. I always wanted more diffusion when I worked with it.

The globe flash doesn't quite eliminate all specular reflections, some images still have hot spots when using it, but they are a much reduced level than the other two flashes. Typically they show up as a bright area rather than a totally over-exposed spot. Compared to any previous flash I have used this is great performance.

It isn't entirely a fair comparison since the photos are ordered chronologically and were taken a few months apart so I learned as I went. Also, the dedicated macro flashes give more control over shadows. Still, the DIY globe flash I am using is almost half the price of the Sigma flash, and and a quarter the price of the Sony flash.

The previous globe flash I used almost had this level of performance, but I found two somewhat annoying issues. Too little light got in meaning the flash took a long time to recharge and it had oddly shaped reflections on shiny surfaces. You can see the diffuser shaped reflections on the ants in the photo below:


So I upgraded from a 6" globe to an 8" globe. I chose 8" because that puts a subject at minimum focus distance right at the center of the light source. I obsessively keep subjects at minimum focus distance so I can add scale bars.

Going to an 8" globe created problems attaching the globe to the camera. The 8" globes do not come with smaller than 4" holes. That is larger than any cheap adapter I saw. So I had to purchase an acrylic disc to use to connect the step up ring to the globe.

The list of materials and tools for the project were:
First I used the dremel cut a hole in the acrylic disc matching the opening on the lens, then I cut off the flange attached to the globe and epoxied the step up ring, acrylic disc, and globe together. Once the epoxy dried I used the dremel to cut the globe into the shape I thought would work best:



As you can see the new flash diffuser is significantly larger than the old one. Just like last time, too little light makes it from the flash to the diffuser. This was easily solved by putting a paper towel above the two. In an attempt to ruggedize it, I covered the paper with packing tape.

If I used a 12" globe I could probably avoid the paper towel, and I will probably ultimately find a better way to trap the light than the paper towel. It does seem effective though.

This has been very successful. Unlike the old version I can fire off photos rapidly using this version. Also, while reflections aren't entirely gone, the smaller black area on the central hole and larger globe make the reflections less obviously the shape of my diffuser.

While the diffuser produces very good images, I have found some downsides:
  1. The shape makes it difficult to image insects in a tight space. 
  2. You look like a crazy person when you walk down the street carrying this camera. Honestly this is a problem with all macro flashes though.
  3. Diffusion could still be improved! This seems the best trade off of usefulness and image quality but I still often find myself wanting more diffusion. The only viable way I see to get more diffusion without making the system hopelessly bulky would be to use two small flashes, one on each side of the globe. 
  4. The paper towel is a pain to take on and off. Maybe a little aluminum foil hat for the flash? Maybe a white cloth with velcro?

This could be adapted to just about any macro lens. The only big change would be to use a different size step up ring to connect to whatever lens you want. I suspect it might even work on a superzoom camera with the on camera flash, but I have not tried.

Wednesday, March 21, 2018

Globe Flash

After my recent experiment with using a handheld flash for macro, I learned a few things. Most important of these things is that shadows are for artists. As someone who is mostly trying to take a whole bunch of high quality photos of insects in a hurry, shadows are not my friend. Ending up with a shadow covering an important part of an insect for identification is a real problem with that setup. Also it was bulky and a lot of work.

After some research on alternatives I ran into a clever flash which uses a globe shade off of a lamp as a diffuser. This made a whole lot of sense to me since the best diffusion comes from a sphere of light around the subject. I can't quite get there with a globe cut in pieces, but I can get a whole lot closer than with just about any alternative. The globe also reduces shadows since light is coming from a bunch of angles.

So I bought a six inch acrylic globe and went to work. 

There are a few challenging parts to making this setup work. First was cutting acrylic. This isn't necessary if you can find a hard plastic globe, but acrylic ones are much easier to find so I bought one of them. My first attempt  was with a hack saw. With sufficient patience this may work, I got tired of cutting though, rushed through, and cracked it. After that I tried cutting with a dremel tool. That seemed to work well.

The next problem is how do you attach the globe to the camera? My first thought was to order a 3D printed attachment to where the lens hood connects. This is probably the right answer, but I got lazy since this would require some real work. Eventually I realized a simpler solution is to buy an adapter ring from 62mm(the lens threads) to 77mm(the diameter of the globe). Then I epoxied the globe to the adapter:
 I am not quite sure how durable the epoxy/adapter connection will prove. If it does hold up though, this is a great solution for how to connect the globe.

After a bit of use, I realized  another problem. The shade blocks too much light! What ends up happening is that the background turns white because it is not shaded, and the area focused on is often too dark. Worse, the setup only works at minimum focus distance! Once the subject is further away, there is a big bright area which is not blocked by the globe, and a dark area which is.

A paper towel seemed to fix these problem, although using a 10 or 12 inch globe would probably be a better solution.

I have only used this setup two days, but so far results have been remarkable. To use an example everyone knows, here is a photo of a fruit fly. Extra diffusion from the wall, probably made it better than it otherwise would be but still it is impressive results from such a low cost flash:


This gets even more impressive when compared side by side with a photo using the same lens/camera and the Sony Twin Flash which was four times the price as this flash. The bright spots from reflection stand out much more with that setup:





Monday, February 26, 2018

Rancho La Habra Draft EIR Comments



 After a few boring months, we finally have a development in La Habra worth commenting to the city on. As usual, the a draft EIR was developed which fails to see the huge amount of harm to the residents of California which housing restrictions have caused.

Here are the comments I submitted:

The draft environmental impact report for the Rancho La Habra Specific Plan largely fails to see the big picture of the environmental impact from development of this housing. The project is blamed for a great many problems which are either not environmental problems, or will not actually be impacted by this project. A more reasonable analysis of the impact of this project would find that the actual lowest environmental impact of this project could be obtained by dramatically increasing the density of housing development, perhaps to the level of other recent projects along Beach Boulevard.

The environmental impact report blames the project for increasing population and states that this is a significant unavoidable impact. The project will do no such thing. The people who will live in the development are already born and there is no reason to think that the project will lead to increased birth rates in the future. The project will not increase the population. It will only increase the number of those people who live in La Habra. The significant environmental question is, would the environmental impact of this population be reduced or increased if these people move to La Habra? The answer is a very clear reduction. If this project is not constructed these people will find housing elsewhere. This housing will almost certainly have a higher environmental impact than this development due to the mild climate, minimal disturbance of wildlife habitat and central location of this project which will reduce environmental impacts when compared to exurban developments in the inland empire. 

Elsewhere the EIR repeatedly mentions increases in traffic as an unavoidable environmental problem. This is quite simply not an environmental problem. The environmental problem is cars, not traffic. If there is an environmental impact relating to transit which should be considered it is from the fact that this development will never support decent public transportation. Were the density to be tripled or quadrupled, it would plausibly be a high enough density urban area to support reasonable public transit service. As it is, the development is simply too low density to ever support good public transit. Unlike increased traffic from this project, this is a serious environmental impact. Also, the design could reduce driving by providing easier walking access to neighboring businesses, making these distances as short as practical and removing gates which are likely to reduce the number of people who walk. 

Again greenhouse gas emissions are over-stated because of a failure to understand what would happen were this development is not constructed. These people will live somewhere. The average resident will certainly be closer to their worksite if this development is constructed, reducing miles driven. The average resident will certainly be using less heating and cooling if this development is constructed, again reducing energy use and greenhouse gas emissions.

None of the evaluated alternatives properly account of the reduced environmental impacts which could be realized by increasing density. The amount of preserved habitat, viability of public transit, walkability, total greenhouse gas emissions, and even total revenue to the developer could all be improved by reducing the amount of land developed while increasing the total number of housing units installed. This is a dramatically superior option to all six alternatives considered in the draft EIR.

Friday, January 19, 2018

I am always tweaking my camera setup to try and squeeze the most out of it. My base setup of a Sony a6300 with a Sony FE 90mm Macro Lens is about as good as anything on the market. However flashes have always given me a lot more trouble.

First I got a Sigma Ring Flash. It did alright, but it unfortunately isn't really a ring flash. It is a twin flash which is built with no easy way to provide diffusion. That has lead to disappointing image quality compared to some other products on the market.

After six months of using the ring flash, I got a ridiculously good deal on to a Sony Twin Flash. This was a really solid macro flash. It suffered from a few problems though. It was pretty fussy, with lots of little pieces which always needed adjusting. It also it lacked high speed sync which made it almost useless for taking photos in full sun. Worst of all, it died in about six months. It was under warranty, but Sony refused to replace it and instead refunded it. Since I got such a good deal, buying another one with the money I got wasn't an option so I went back to the ring flash for another year.

After researching more, I decided that the way to go was a hand held flash. Something like what is done in this video. That is a far lower cost alternative than a dedicated macro flash. However it created some conundrums. How do you photograph at night when holding a flashlight? Also, I am usually dragging kids down trails so I often need two hands. So I decided to get a flash bracket which my flash usually goes to, but get a quick release to allow me to remove it and use it as a hand held flash.

The basic setup is:
Godox Ving V860IIS flash
X1T-S Wireless Flash Trigger
Diffuser
Straight Flash Bracket
Quick Release Plate.

I bought a packaged deal which included the first three items, but with a diffuser which is perhaps too small. Then I bought the larger diffuser because I wasn't sure what I wanted. Here is what the setup looks like:

This setup really does produce much better images than the sigma ring flash. Here are two very tiny Big-Headed Ants, one with the ring flash and the other with the Godox:


The lack of diffusion with the ring flash (top) leads to a lot more white spots on reflective surfaces. Also, the shadows are always coming to the far side of the camera. In a way this is good, the side you are looking at is illuminated. However, a more artistic type would probably complain about the inability to control the location of the shadows.

I am also trying this with a much larger 13"x8" diffuser. This diffuser is probably too large, but it does seem to give fantastic results so I may keep using it.


Using the larger diffuser seems to give fantastic results, but it messes up the center of mass of the camera rig so bad that it is unwieldy. Whether the slightly higher image quality is worth the fuss, I have yet to decide. I may get a medium sized diffuser in a few weeks.

This whole system is really an amazing deal. For under $300 you get a flash which can do TTL, High Speed Sync, and is radio controlled. It also can shoot thousands of macro shots on a single battery due to the Lithium ion battery. Unlike the similarly priced Sigma Ring Flash this flash is also useful for more than just macro as it is a typical speedlight.

Someone who wanted to reduce the cost could go with the Godox TT685S, it is basically the same flash just with AA batteries.

Someone trying to save cost and weight could go with the Godox TT350S. That flash reduces cost but at the cost of lower recycle times and lower maximum power.

Someone trying to save money could also go with a TTL flash cord. I don't actually recommend it though. The radio flash works amazingly well and the TTL cords seem over priced. There is a trick though with the transmitter, you need to turn it onto macro mode. This is done by holding down the test button while turning the transmitter on. If you forget to do this, it sometimes fails to fire unless it is more than 1 foot from the transmitter.

Someone wanting a bit higher quality flashes could use the Sony HVL-F45RM flash with the Sony Radio Control Wireless Commander. Again, I don't really recommend it. The setup costs three times as much for a slightly less powerful flash.