Photography exposure

From Pynomo
Revision as of 19:23, 25 September 2008 by WikiSysop (Talk | contribs) (Source code)

Jump to: navigation, search

Photography exposure

Photography exposure
Ex photo exposure.png
author Leif Roschier

Theory and background

References


Construction of the nomograph

Generated nomograph

Second order equation
Ex photo exposure.png
Generated portable document file (pdf): File:Ex photo exposure.pdf

Source code

"""
    ex_photo_exposure.py
 
    Photgraph exposure.
 
    Copyright (C) 2007-2008  Leif Roschier
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""
from nomographer import *
"""
functions for solartime taken from solareqns.pdf from
http://www.srrb.noaa.gov/highlights/sunrise/solareqns.PDF
"""
# fractional year
def gamma(day):
    return 2*pi/365.0*(day-1+0.5)
# equation of time
def eq_time(day):
    gamma0=gamma(day)
    return 229.18*(0.000075+0.001868*cos(gamma0)-0.032077*sin(gamma0)\
                   -0.014615*cos(2*gamma0)-0.040849*sin(2*gamma0))
 
# mean correction, with constant correction we make less than 1.5 minutes error
# in time axis
temp_a=arange(0,2*pi,0.001)
temp_b=eq_time(temp_a)
correction=mean(temp_b) # this is about four minutes
 
# declination
def eq_declination(day):
    g0=gamma(day)
    return 0.006918-0.399912*cos(g0)+0.070257*sin(g0)-0.006758*cos(2*g0)\
            +0.000907*sin(2*g0)-0.002697*cos(3*g0)+0.00148*sin(3*g0)
 
def f1(dummy):
    return 0.0
def g1(fii):
    return cos(fii*pi/180.0)
 
def f2(lat,day):
    dec=eq_declination(day)
    return (cos(lat*pi/180.0)*cos(dec))/(1.0+(cos(lat*pi/180.0)*cos(dec)))
def g2(lat,day):
    dec=eq_declination(day) # in radians
    return (sin(lat*pi/180.0)*sin(dec))/(1.0+(cos(lat*pi/180.0)*cos(dec)))
 
def f3(dummy):
    return 1
def g3(h):
    hr=(h*60.0+correction)/4.0-180.0
    return -1.0*cos(hr*pi/180.0)
 
days_in_month = (31,28,31,30,31,30,31,31,30,31,30,31)
times1=[]
for idx in range(0,12):
    times1.append(sum(days_in_month[0:idx])+1)
 
 
#times=linspace(0,350,10)
times=arange(0.0,360.0,10.0,dtype=double).tolist()
time_titles=['January','February','March','April','May','June',
             'July','August','September','October','November','December']
 
 
phi_params={
        'u_min':0.0,
        'u_max':90.0,
        'u_min_trafo':0.0,
        'u_max_trafo':90.0,
        'f':f1,
        'g':g1,
        'h':lambda u:1.0,
        'title':r'Solar zenith angle $\phi$',
        'title_x_shift':0.0,
        'title_y_shift':0.25,
        'scale_type':'linear',
        'tick_levels':2,
        'tick_text_levels':1,
        'tick_side':'right',
        'tag':'phi',
        'grid':False,
        'extra_params':[{'u_min':20.0,
                         'u_max':90.0,
                         'tick_levels':4,
                         'tick_text_levels':2,
                         }]
        }
 
time_params={
        'u_min':0.0,
        'u_max':23.0,
        'u_min_trafo':0.0,
        'u_max_trafo':12.0,
        'f':f3,
        'g':g3,
        'h':lambda u:1.0,
        'title':r'Hour (h)',
        'title_x_shift':0.0,
        'title_y_shift':0.25,
        'scale_type':'linear',
        'tick_levels':2,
        'tick_text_levels':1,
        'tick_side':'right',
        'tag':'none',
        'grid':False,
        }
 
lat_day_params={
    'ID':'none', # to identify the axis
    'tag':'none', # for aligning block wrt others
    'title':'Grid',
    'title_x_shift':0.0,
    'title_y_shift':0.25,
    'title_distance_center':0.5,
    'title_opposite_tick':True,
    'u_min':20.0, # for alignment
    'u_max':80.0,  # for alignment
    'f_grid':f2,
    'g_grid':g2,
    'h_grid':lambda u,v:1.0,
    'u_start':30.0,
    'u_stop':80.0,
    'v_start':times1[0], # day
    'v_stop':times1[-1],
    'u_values':[30.0,40.0,50.0,60.0,70.0,80.0],
    'u_texts':['30','40','50','Latitude = 60','70','80'],
    'v_values':times1,
    'v_texts':time_titles,
    'grid':True,
    'text_prefix_u':r'',
    'text_prefix_v':r'',
    'text_distance':0.5,
    'v_texts_u_start':False,
    'v_texts_u_stop':True,
    'u_texts_v_start':False,
    'u_texts_v_stop':True,
    }
 
block_params={
             'block_type':'type_9',
             'f1_params':phi_params,
             'f2_params':lat_day_params,
             'f3_params':time_params,
             'transform_ini':True,
             }
 
def limit_xx(x):
    x1=x
    if x1>1.0:
        x1=1.0
    if x1<-1.0:
        x1=-1.0
    return x1
 
def limit_x(x):
    x1=x
    if not x1>0.0:
        x1=0.0001
    return x1
 
const_A=0.33766
const_B=-13.656
 
block_params_weather={
   'block_type':'type_5',
   'u_func':lambda u:u,
   'v_func':lambda x,v:const_A+const_B*log10(limit_x(x))+v,
   #'u_values':[1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,15.0,20,25],
   'u_values':[1.0,25.0],
   'u_manual_axis_data':{1.0:'',
                         25.0:''},
   'v_values':[0.0,1.0,3.0,6.0,9.0,12.0],
   'v_manual_axis_data': {0.0:['Clear sky, Cumulus clouds',{'x_corr':0.5,
                                                            'y_corr':0.0,
                                                            'draw_line':False}],
                     1.0:'Clear sky',
                     3.0:'Sun through clouds',
                     6.0:'Sky light gray',
                     9.0:'Sky dark gray',
                     12.0:'Thunder-clouds cover sky',
                     },
   'v_text_distance':0.5,
   'wd_tick_levels':0,
   'wd_tick_text_levels':0,
   'wd_tick_side':'right',
   'wd_title':'',
   'manual_x_scale':True,
   'x_min':0.06,
   'x_max':0.99,
   'u_title':'',
   'v_title':'',
   'wd_title_opposite_tick':True,
   'wd_title_distance_center':2.5,
   'wd_align_func':lambda L:acos(limit_xx(10.0**((L-const_A)/const_B)))*180.0/pi, # phi as L
   'wd_func':lambda L:10.0**((L-const_A)/const_B), # x as L
   'wd_func_inv':lambda x:const_A+const_B*log10(x), # L as x
   'wd_tag':'phi',
   'mirror_y':True,
   'mirror_x':False,
   'width':10.0,
   'height':10.0,
   'u_scale_opposite':True,
   'u_tag':'AA',
   'horizontal_guides':True,
 }
 
block_params_scene={
   'block_type':'type_5',
   'u_func':lambda u:u,
   'v_func':lambda x,v:x+v,
   'u_values':[1.0,25.0],
   'u_manual_axis_data':{1.0:'',
                         25.0:''},
   'u_tag':'AA',
   'wd_tag':'EV',
   'v_values':[-4.0,-1.0,2.0,5.0,7.0,9.0,11.0,13.0,15.0],
   'v_manual_axis_data': {-6.0:'Person under trees',
                          -4.0:'Inside forest',
                          -1.0:'Person in shadow of wall',
                          2.0:'Person at open place; alley under trees',
                          5.0:'Buildings; street',
                          7.0:'Landscape and front matter',
                          9.0:'Open landscape',
                          11.0:'Snow landscape and front matter; beach',
                          13.0:'Snow field; open sea',
                          15.0:'Clouds',
                          },
   'wd_tick_levels':0,
   'wd_tick_text_levels':0,
   'wd_tick_side':'right',
   'wd_title':'',
   'u_title':'',
   'v_title':'',
   'wd_title_opposite_tick':True,
   'wd_title_distance_center':2.5,
   'mirror_x':True,
   'horizontal_guides':True,
   'u_align_y_offset':-0.9,
 }
 
 
camera_params_1={
        'u_min':-10.0,
        'u_max':15.0,
        'function':lambda u:u,
        'title':r'',
        'tick_levels':0,
        'tick_text_levels':0,
        'tag':'EV',
                }
camera_params_2={
        'u_min':10.0,
        'u_max':12800.0,
        'function':lambda S:-(10*log10(S)+1.0),
        'title':r'Film speed',
        'manual_axis_data': {10.0:'ISO 10',
                             20.0:'ISO 20',
                             #40.0:'ISO 40',
                             50.0:'ISO 50',
                             100.0:'ISO 100',
                             200.0:'ISO 200',
                             400.0:'ISO 400',
                             800.0:'ISO 800',
                             1600.0:'ISO 1600',
                             3200.0:'ISO 3200',
                             6400.0:'ISO 6400',
                             12800.0:'ISO 12800',
                             },
        'scale_type':'manual line'
                }
camera_params_3={
        'u_min':0.1,
        'u_max':10000.0,
        'function':lambda t:-10*log10((1.0/t)/(1.0/10.0))-30,
        'manual_axis_data': {1/10.0:'10',
                             1/7.0:'7',
                             1/5.0:'5',
                             1/3.0:'3',
                             1/2.0:'2',
                             1.0:'1',
                             2.0:'1/2',
                             3.0:'1/3',
                             5.0:'1/5',
                             7.0:'1/7',
                             10.0:'1/10',
                             20.0:'1/20',
                             30.0:'1/30',
                             50.0:'1/50',
                             70.0:'1/70',
                             100.0:'1/100',
                             200.0:'1/200',
                             300.0:'1/300',
                             500.0:'1/500',
                             700.0:'1/700',
                             1000.0:'1/1000',
                             2000.0:'1/2000',
                             3000.0:'1/3000',
                             5000.0:'1/5000',
                             7000.0:'1/7000',
                             10000.0:'1/10000',
                             },
        'scale_type':'manual line',
        'title':r't (s)',
        'text_format':r"1/%3.0f s"
                }
#          6.7     8     9.5     11     13     16     19     22
camera_params_4={
        'u_min':1.0,
        'u_max':22.0,
        'function':lambda N:10*log10((N/3.2)**2)+30,
        'manual_axis_data': {1.0:'f/1',
                             1.2:'f/1.2',
                             1.4:'f/1.4',
                             1.7:'f/1.7',
                             2.0:'f/2',
                             2.4:'f/2.4',
                             2.8:'f/2.8',
                             3.3:'f/3.3',
                             4.0:'f/4',
                             4.8:'f/4.8',
                             5.6:'f/5.6',
                             6.7:'f/6.7',
                             8.0:'f/8',
                             9.5:'f/9.5',
                             11.0:'f/11',
                             13.0:'f/13',
                             16.0:'f/16',
                             19.0:'f/19',
                             22.0:'f/22',
                             },
        'scale_type':'manual line',
        'title':r'Aperture',
                }
 
block_params_camera={
             'block_type':'type_3',
             'width':10.0,
             'height':10.0,
             'f_params':[camera_params_1,camera_params_2,camera_params_3,
                         camera_params_4],
             'mirror_x':True,
             }
 
def old_EV(EV):
    return (-EV+13.654)/0.3322
 
EV_para={
        'tag':'EV',
        'u_min':4.0,
        'u_max':19.0,
        'function':lambda u:old_EV(u),
        'title':r'EV$_{100}$',
        'tick_levels':1,
        'tick_text_levels':1,
        'align_func':old_EV,
        'title_x_shift':0.5,
        'tick_side':'right',
        }
EV_block={
         'block_type':'type_8',
         'f_params':EV_para
            }
 
 
main_params={
              'filename':'ex_photo_exposure.pdf',
              'paper_height':35.0,
              'paper_width':35.0,
              'block_params':[block_params,block_params_weather,block_params_scene,block_params_camera,EV_block],
              #'block_params':[block_params_weather,block_params_scene,block_params_camera,EV_block],
              'transformations':[('rotate',0.01),('scale paper',)],
              'title_x': 7,
              'title_y': 34,
              'title_box_width': 10,
              'title_str':r'Photography exposure (Setala 1940) \copyright Leif Roschier  2008 '
              }
b=Nomographer(main_params)