Changeset 9404dd3 in sasmodels


Ignore:
Timestamp:
Dec 4, 2015 10:41:47 AM (9 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, costrafo411, magnetic_model, release_v0.94, release_v0.95, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
eaca9eb
Parents:
7bb290c
Message:

python 3.x support

Files:
17 edited

Legend:

Unmodified
Added
Removed
  • doc/conf.py

    r0496031 r9404dd3  
    2222sys.path.insert(0, os.path.abspath('_extensions')) 
    2323sys.path.insert(0, os.path.abspath('.')) # needed for extension tests 
    24 print "\n".join(sys.path) 
     24print("\n".join(sys.path)) 
    2525import sasmodels 
    2626 
  • doc/gentoc.py

    r7bb290c r9404dd3  
     1from __future__ import print_function 
     2 
    13import sys 
    24# make sure sasmodels is on the path 
     
    3941def _maybe_make_category(category, models, cat_files, model_toc): 
    4042    if category not in cat_files: 
    41         print >>sys.stderr, "Unexpected category %s containing"%category, models 
     43        print("Unexpected category %s containing"%category, models, file=sys.stderr) 
    4244        title = category.capitalize()+" Functions" 
    4345        cat_files[category] = _make_category(category, category, title, model_toc) 
     
    4547def generate_toc(model_files): 
    4648    if not model_files: 
    47         print >>sys.stderr, "gentoc needs a list of model files" 
     49        print("gentoc needs a list of model files", file=sys.stderr) 
    4850 
    4951    # find all categories 
     
    5557        model_definition = load_model_definition(model_name) 
    5658        if not hasattr(model_definition, 'category'): 
    57             print >>sys.stderr, "Missing category for",item 
     59            print("Missing category for", item, file=sys.stderr) 
    5860        else: 
    5961            category.setdefault(model_definition.category,[]).append(model_name) 
     
    6264    for k,v in category.items(): 
    6365        if len(v) == 1: 
    64             print >>sys.stderr, "Category %s contains only %s"%(k,v[0]) 
     66            print("Category %s contains only %s"%(k,v[0]), file=sys.stderr) 
    6567 
    6668    # Generate category files for the table of contents. 
  • sasmodels/bumps_model.py

    r0e9048f r9404dd3  
    122122            fixed_pars = [getattr(self.model, p).value for p in self._fn.fixed_pars] 
    123123            pd_pars = [self._get_weights(p) for p in self._fn.pd_pars] 
    124             #print fixed_pars,pd_pars 
     124            #print(fixed_pars,pd_pars) 
    125125            Iq_calc = self._fn(fixed_pars, pd_pars, self.cutoff) 
    126126            #self._theory[:] = self._fn.eval(pars, pd_pars) 
     
    137137 
    138138    def residuals(self): 
    139         #if np.any(self.err ==0): print "zeros in err" 
     139        #if np.any(self.err ==0): print("zeros in err") 
    140140        return (self.theory() - self.Iq) / self.dIq 
    141141 
    142142    def nllf(self): 
    143143        delta = self.residuals() 
    144         #if np.any(np.isnan(R)): print "NaN in residuals" 
     144        #if np.any(np.isnan(R)): print("NaN in residuals") 
    145145        return 0.5 * np.sum(delta ** 2) 
    146146 
  • sasmodels/compare.py

    r1ec7efa r9404dd3  
    7171    """ 
    7272    # convert model parameters from sasmodel form to sasview form 
    73     #print "old",sorted(pars.items()) 
     73    #print("old",sorted(pars.items())) 
    7474    modelname, pars = revert_model(model_definition, pars) 
    75     #print "new",sorted(pars.items()) 
     75    #print("new",sorted(pars.items())) 
    7676    sas = __import__('sas.models.'+modelname) 
    7777    ModelClass = getattr(getattr(sas.models,modelname,None),modelname,None) 
     
    193193    try: 
    194194        model = core.load_model(model_definition, dtype=dtype, platform="ocl") 
    195     except Exception,exc: 
    196         print exc 
    197         print "... trying again with single precision" 
     195    except Exception as exc: 
     196        print(exc) 
     197        print("... trying again with single precision") 
    198198        model = core.load_model(model_definition, dtype='single', platform="ocl") 
    199199    calculator = DirectModel(data, model, cutoff=cutoff) 
     
    267267        seed = int(opt_values['-random']) if '-random' in opt_values else None 
    268268        pars, seed = randomize_model(pars, seed=seed) 
    269         print "Randomize using -random=%i"%seed 
     269        print("Randomize using -random=%i"%seed) 
    270270    pars.update(set_pars)  # set value after random to control value 
    271271    constrain_pars(model_definition, pars) 
     
    275275        suppress_pd(pars) 
    276276    if '-pars' in opts: 
    277         print "pars",parlist(pars) 
     277        print("pars "+str(parlist(pars))) 
    278278 
    279279    # Base calculation 
     
    287287            base, base_time = eval_sasview(model_definition, pars, data, Ncomp) 
    288288            base_name = "sasview" 
    289             #print "base/sasview", (base-pars['background'])/(comp-pars['background']) 
    290             print "sasview t=%.1f ms, intensity=%.0f"%(base_time, sum(base)) 
    291             #print "sasview",comp 
     289            #print("base/sasview", (base-pars['background'])/(comp-pars['background'])) 
     290            print("sasview t=%.1f ms, intensity=%.0f"%(base_time, sum(base))) 
     291            #print("sasview",comp) 
    292292        except ImportError: 
    293293            traceback.print_exc() 
     
    297297                                    dtype=dtype, cutoff=cutoff, Nevals=Nbase) 
    298298        base_name = "ocl" 
    299         print "opencl t=%.1f ms, intensity=%.0f"%(base_time, sum(base)) 
    300         #print "base", base 
    301         #print max(base), min(base) 
     299        print("opencl t=%.1f ms, intensity=%.0f"%(base_time, sum(base))) 
     300        #print("base " + base) 
     301        #print(max(base), min(base)) 
    302302 
    303303    # Comparison calculation 
     
    306306                                    dtype=dtype, cutoff=cutoff, Nevals=Ncomp) 
    307307        comp_name = "ctypes" 
    308         print "ctypes t=%.1f ms, intensity=%.0f"%(comp_time, sum(comp)) 
     308        print("ctypes t=%.1f ms, intensity=%.0f"%(comp_time, sum(comp))) 
    309309    elif Ncomp > 0: 
    310310        try: 
    311311            comp, comp_time = eval_sasview(model_definition, pars, data, Ncomp) 
    312312            comp_name = "sasview" 
    313             #print "base/sasview", (base-pars['background'])/(comp-pars['background']) 
    314             print "sasview t=%.1f ms, intensity=%.0f"%(comp_time, sum(comp)) 
    315             #print "sasview",comp 
     313            #print("base/sasview", (base-pars['background'])/(comp-pars['background'])) 
     314            print("sasview t=%.1f ms, intensity=%.0f"%(comp_time, sum(comp))) 
     315            #print("sasview",comp) 
    316316        except ImportError: 
    317317            traceback.print_exc() 
     
    320320    # Compare, but only if computing both forms 
    321321    if Nbase > 0 and Ncomp > 0: 
    322         #print "speedup %.2g"%(comp_time/base_time) 
    323         #print "max |base/comp|", max(abs(base/comp)), "%.15g"%max(abs(base)), "%.15g"%max(abs(comp)) 
     322        #print("speedup %.2g"%(comp_time/base_time)) 
     323        #print("max |base/comp|", max(abs(base/comp)), "%.15g"%max(abs(base)), "%.15g"%max(abs(comp))) 
    324324        #comp *= max(base/comp) 
    325325        resid = (base - comp) 
    326326        relerr = resid/comp 
    327327        #bad = (relerr>1e-4) 
    328         #print relerr[bad],comp[bad],base[bad],data.qx_data[bad],data.qy_data[bad] 
     328        #print(relerr[bad],comp[bad],base[bad],data.qx_data[bad],data.qy_data[bad]) 
    329329        _print_stats("|%s-%s|"%(base_name,comp_name)+(" "*(3+len(comp_name))), resid) 
    330330        _print_stats("|(%s-%s)/%s|"%(base_name,comp_name,comp_name), relerr) 
     
    379379        "zero-offset:%+.3e"%np.mean(err), 
    380380        ] 
    381     print label,"  ".join(data) 
     381    print(label+"  ".join(data)) 
    382382 
    383383 
     
    466466        sys.exit(1) 
    467467    if args[0] not in MODELS: 
    468         print "Model %r not available. Use one of:\n    %s"%(args[0],models) 
     468        print("Model %r not available. Use one of:\n    %s"%(args[0],models)) 
    469469        sys.exit(1) 
    470470    if len(args) > 3: 
     
    475475                  and not any(o.startswith('-%s='%t) for t in VALUE_OPTIONS)] 
    476476    if invalid: 
    477         print "Invalid options: %s"%(", ".join(invalid)) 
     477        print("Invalid options: %s"%(", ".join(invalid))) 
    478478        sys.exit(1) 
    479479 
     
    500500            # extract base name without distribution 
    501501            s = set(p.split('_pd')[0] for p in pars) 
    502             print "%r invalid; parameters are: %s"%(k,", ".join(sorted(s))) 
     502            print("%r invalid; parameters are: %s"%(k,", ".join(sorted(s)))) 
    503503            sys.exit(1) 
    504504        set_pars[k] = float(v) if not v.endswith('type') else v 
  • sasmodels/compare_many.py

    r4b41184 r9404dd3  
    5353            raise 
    5454        except: 
    55             print >>sys.stderr, traceback.format_exc() 
    56             print >>sys.stderr, "when comparing",name,"for seed",seed 
     55            traceback.print_exc() 
     56            print("when comparing %s for %d"%(name, seed)) 
    5757            if hasattr(data, 'qx_data'): 
    5858                result = np.NaN*data.data 
     
    7171    max_diff = [0] 
    7272    for k in range(N): 
    73         print >>sys.stderr, name, k 
     73        print("%s %d"%(name, k)) 
    7474        pars_i, seed = randomize_model(pars) 
    7575        constrain_pars(model_definition, pars_i) 
     
    109109        else: 
    110110            print(("%d,"%seed)+','.join("%g"%v for v in columns)) 
    111     print '"good","%d/%d","max diff",%g'%(num_good, N, max_diff[0]) 
     111    print('"good","%d/%d","max diff",%g'%(num_good, N, max_diff[0])) 
    112112 
    113113 
    114114def print_usage(): 
    115     print "usage: compare_many.py MODEL COUNT (1dNQ|2dNQ) (CUTOFF|mono) (single|double|quad)" 
     115    print("usage: compare_many.py MODEL COUNT (1dNQ|2dNQ) (CUTOFF|mono) (single|double|quad)") 
    116116 
    117117 
     
    155155    model = sys.argv[1] 
    156156    if not (model in MODELS) and (model != "all"): 
    157         print 'Bad model %s.  Use "all" or one of:' 
     157        print('Bad model %s.  Use "all" or one of:') 
    158158        print_models() 
    159159        sys.exit(1) 
  • sasmodels/core.py

    r7cf2cfd r9404dd3  
    179179        value, weight = dispersion_mesh(vol_pars) 
    180180        individual_radii = ER(*value) 
    181         #print values[0].shape, weights.shape, fv.shape 
     181        #print(values[0].shape, weights.shape, fv.shape) 
    182182        return np.sum(weight*individual_radii) / np.sum(weight) 
    183183 
  • sasmodels/data.py

    rac21c7f r9404dd3  
    274274            plt.subplot(121) 
    275275 
    276         #print vmin, vmax 
     276        #print(vmin, vmax) 
    277277        positive = False 
    278278        if plot_data: 
  • sasmodels/direct_model.py

    r7cf2cfd r9404dd3  
    140140 
    141141    if len(sys.argv) < 3: 
    142         print "usage: python -m sasmodels.direct_model modelname (q|qx,qy) par=val ..." 
     142        print("usage: python -m sasmodels.direct_model modelname (q|qx,qy) par=val ...") 
    143143        sys.exit(1) 
    144144    model_name = sys.argv[1] 
     
    156156            data = empty_data2D([qx],[qy]) 
    157157        else: 
    158             print "use q or qx,qy or ER or VR" 
     158            print("use q or qx,qy or ER or VR") 
    159159            sys.exit(1) 
    160160    else: 
     
    168168                for k,v in [pair.split('=')]) 
    169169    if call == "ER": 
    170         print calculator.ER(**pars) 
     170        print(calculator.ER(**pars)) 
    171171    elif call == "VR": 
    172         print calculator.VR(**pars) 
     172        print(calculator.VR(**pars)) 
    173173    else: 
    174174        Iq = calculator(**pars) 
    175         print Iq[0] 
     175        print(Iq[0]) 
    176176 
    177177if __name__ == "__main__": 
  • sasmodels/exception.py

    rd138d43 r9404dd3  
    2020        >>> D = {} 
    2121        >>> try: 
    22         ...    print D['hello'] 
    23         ... except Exception,exc: 
     22        ...    print(D['hello']) 
     23        ... except Exception as exc: 
    2424        ...    annotate_exception(exc, "while accessing 'D'") 
    2525        ...    raise 
  • sasmodels/generate.py

    re88bb78 r9404dd3  
    546546        defines.append(('IQXY_HAS_THETA', '1')) 
    547547 
    548     #for d in defines: print d 
     548    #for d in defines: print(d) 
    549549    DEFINES = '\n'.join('#define %s %s' % (k, v) for k, v in defines) 
    550550    SOURCES = '\n\n'.join(source) 
     
    558558    Interpret the model definition file, categorizing the parameters. 
    559559    """ 
    560     #print kernelfile 
     560    #print(kernelfile) 
    561561    category = getattr(kernel_module, 'category', None) 
    562562    parameters = COMMON_PARAMETERS + kernel_module.parameters 
     
    655655    make(cylinder) 
    656656    toc = (datetime.datetime.now() - tic).total_seconds() 
    657     print "time:", toc 
     657    print("time: %g"%toc) 
    658658 
    659659def main(): 
    660660    if len(sys.argv) <= 1: 
    661         print "usage: python -m sasmodels.generate modelname" 
     661        print("usage: python -m sasmodels.generate modelname") 
    662662    else: 
    663663        name = sys.argv[1] 
     
    666666        model = getattr(sasmodels.models, name) 
    667667        source, _ = make(model) 
    668         print source 
     668        print(source) 
    669669 
    670670if __name__ == "__main__": 
  • sasmodels/kernelcl.py

    r92da231 r9404dd3  
    5757    # Ask OpenCL for the default context so that we know that one exists 
    5858    cl.create_some_context(interactive=False) 
    59 except Exception, exc: 
     59except Exception as exc: 
    6060    warnings.warn(str(exc)) 
    6161    raise RuntimeError("OpenCL not available") 
     
    184184        try: 
    185185            self.context = cl.create_some_context(interactive=False) 
    186         except Exception, exc: 
     186        except Exception as exc: 
    187187            warnings.warn(str(exc)) 
    188188            warnings.warn("pyopencl.create_some_context() failed") 
     
    191191    def compile_program(self, name, source, dtype): 
    192192        if name not in self.compiled: 
    193             #print "compiling",name 
     193            #print("compiling",name) 
    194194            self.compiled[name] = compile_model(self.context, source, dtype) 
    195195        return self.compiled[name] 
     
    359359                if pd_pars else np.empty(0, dtype=self.q_input.dtype) 
    360360            loops = np.ascontiguousarray(loops.T, self.q_input.dtype).flatten() 
    361             #print "loops",Nloops, loops 
    362  
    363             #import sys; print >>sys.stderr,"opencl eval",pars 
    364             #print "opencl eval",pars 
     361            #print("loops",Nloops, loops) 
     362 
     363            #import sys; print("opencl eval",pars) 
     364            #print("opencl eval",pars) 
    365365            if len(loops) > 2 * MAX_LOOPS: 
    366366                raise ValueError("too many polydispersity points") 
  • sasmodels/kerneldll.py

    rd138d43 r9404dd3  
    146146        os.fdopen(fid,"w").write(source) 
    147147        command = COMPILE%{"source":filename, "output":dll} 
    148         print "Compile command:",command 
     148        print("Compile command: "+command) 
    149149        status = os.system(command) 
    150150        if status != 0 or not os.path.exists(dll): 
     
    152152        else: 
    153153            ## uncomment the following to keep the generated c file 
    154             os.unlink(filename); print "saving compiled file in %r"%filename 
     154            os.unlink(filename); print("saving compiled file in %r"%filename) 
    155155    return dll 
    156156 
     
    197197        Npd2d = len(self.info['partype']['pd-2d']) 
    198198 
    199         #print "dll",self.dllpath 
     199        #print("dll",self.dllpath) 
    200200        try: 
    201201            self.dll = ct.CDLL(self.dllpath) 
    202         except Exception, exc: 
     202        except Exception as exc: 
    203203            annotate_exception(exc, "while loading "+self.dllpath) 
    204204            raise 
     
    291291        fixed = [real(p) for p in fixed_pars] 
    292292        args = self.q_input.q_pointers + [self.p_res, nq] + dispersed + fixed 
    293         #print pars 
     293        #print(pars) 
    294294        self.kernel(*args) 
    295295 
  • sasmodels/kernelpy.py

    r062c56d r9404dd3  
    108108 
    109109    def __call__(self, fixed, pd, cutoff=1e-5): 
    110         #print "fixed",fixed 
    111         #print "pd", pd 
     110        #print("fixed",fixed) 
     111        #print("pd", pd) 
    112112        args = self.args[:]  # grab a copy of the args 
    113113        form, form_volume = self.kernel, self.info['form_volume'] 
  • sasmodels/model_test.py

    r2781b2e r9404dd3  
    6868        model_definition = load_model_definition(model_name) 
    6969 
    70         #print '------' 
    71         #print 'found tests in', model_name 
    72         #print '------' 
     70        #print('------') 
     71        #print('found tests in', model_name) 
     72        #print('------') 
    7373 
    7474        # if ispy then use the dll loader to call pykernel 
     
    9393                                     test_method_name, 
    9494                                     platform="ocl", dtype='single') 
    95                 #print "defining", test_name 
     95                #print("defining", test_name) 
    9696                suite.addTest(test) 
    9797 
     
    144144                    pass 
    145145 
    146             except Exception,exc: 
     146            except Exception as exc: 
    147147                annotate_exception(exc, self.test_name) 
    148148                raise 
     
    201201    if models and models[0] == 'opencl': 
    202202        if not HAVE_OPENCL: 
    203             print >>sys.stderr, "opencl is not available" 
     203            print("opencl is not available") 
    204204            return 1 
    205205        loaders = ['opencl'] 
     
    215215        loaders = ['opencl', 'dll'] 
    216216    if not models: 
    217         print >>sys.stderr, """\ 
     217        print("""\ 
    218218usage: 
    219219  python -m sasmodels.model_test [opencl|dll|opencl_and_dll] model1 model2 ... 
     
    221221If model1 is 'all', then all except the remaining models will be tested. 
    222222If no compute target is specified, then models will be tested with both opencl 
    223 and dll; the compute target is ignored for pure python models.""" 
     223and dll; the compute target is ignored for pure python models.""") 
    224224 
    225225        return 1 
  • sasmodels/resolution.py

    rd138d43 r9404dd3  
    134134    Apply the resolution weight matrix to the computed theory function. 
    135135    """ 
    136     #print "apply shapes", theory.shape, weight_matrix.shape 
     136    #print("apply shapes", theory.shape, weight_matrix.shape) 
    137137    Iq = np.dot(theory[None,:], weight_matrix) 
    138     #print "result shape",Iq.shape 
     138    #print("result shape",Iq.shape) 
    139139    return Iq.flatten() 
    140140 
     
    287287    weights = np.zeros((len(q), len(q_calc)), 'd') 
    288288 
    289     #print q_calc 
     289    #print(q_calc) 
    290290    for i, (qi, w, h) in enumerate(zip(q, width, height)): 
    291291        if w == 0. and h == 0.: 
     
    301301            in_x = 1.0 * ((q_calc >= qi-h) & (q_calc <= qi+h)) 
    302302            abs_x = 1.0*(q_calc < abs(qi - h)) if qi < h else 0. 
    303             #print qi - h, qi + h 
    304             #print in_x + abs_x 
     303            #print(qi - h, qi + h) 
     304            #print(in_x + abs_x) 
    305305            weights[i,:] = (in_x + abs_x) * np.diff(q_edges) / (2*h) 
    306306        else: 
     
    320320    u_edges[q_edges > u_limit] = u_limit**2 - qi**2 
    321321    weights = np.diff(np.sqrt(u_edges))/w 
    322     #print "i, qi",i,qi,qi+width 
    323     #print q_calc 
    324     #print weights 
     322    #print("i, qi",i,qi,qi+width) 
     323    #print(q_calc) 
     324    #print(weights) 
    325325    return weights 
    326326 
     
    521521            u = sqrt((qi+h_grid)**2 + w_grid**2) 
    522522            Iu = np.interp(u, q_calc, Iq) 
    523             #print np.trapz(Iu, w_grid, axis=1) 
     523            #print(np.trapz(Iu, w_grid, axis=1)) 
    524524            Is = np.trapz(np.trapz(Iu, w_grid, axis=1), h_grid[:,0]) 
    525525            result[i] = Is / (2*h*w) 
     
    675675        #idx = abs(err) >= tolerance 
    676676        #problem = zip(q[idx], output[idx], answer[idx], err[idx]) 
    677         #print "\n".join(str(v) for v in problem) 
     677        #print("\n".join(str(v) for v in problem)) 
    678678        np.testing.assert_allclose(output, answer, rtol=tolerance) 
    679679 
     
    786786        output = resolution.apply(eval_form(resolution.q_calc, form, pars)) 
    787787        # TODO: 10% is too much error; use better algorithm 
    788         #print np.max(abs(answer-output)/answer) 
     788        #print(np.max(abs(answer-output)/answer)) 
    789789        self.compare(q, output, answer, 0.1) 
    790790 
  • sasmodels/resolution2d.py

    rcd8dde1 r9404dd3  
    179179 
    180180    from sas.dataloader import Data2D 
    181     #for i in range(10): print i, 0.001 + i*0.008/9.0 
    182     #for i in range(100): print i, int(math.floor( (i/ (100/9.0)) )) 
     181    #for i in range(10): print(i, 0.001 + i*0.008/9.0) 
     182    #for i in range(100): print(i, int(math.floor( (i/ (100/9.0)) ))) 
    183183    out = Data2D() 
    184184    out.data = z 
     
    198198    value = smear.get_value() 
    199199    ## All data are ones, so the smeared should also be ones. 
    200     print "Data length =", len(value) 
    201     print " 2D linear function, I = 0 + 1*qy" 
     200    print("Data length =", len(value)) 
     201    print(" 2D linear function, I = 0 + 1*qy") 
    202202    text = " Gaussian weighted averaging on a 2D linear function will " 
    203203    text += "provides the results same as without the averaging." 
    204     print text 
    205     print "qx_data", "qy_data", "I_nonsmear", "I_smeared" 
     204    print(text) 
     205    print("qx_data", "qy_data", "I_nonsmear", "I_smeared") 
    206206    for ind in range(len(value)): 
    207         print x[ind], y[ind], model.evalDistribution([x, y])[ind], value[ind] 
     207        print(x[ind], y[ind], model.evalDistribution([x, y])[ind], value[ind]) 
    208208 
    209209 
     
    218218 
    219219    from DataLoader import Data2D 
    220     #for i in range(10): print i, 0.001 + i*0.008/9.0 
    221     #for i in range(100): print i, int(math.floor( (i/ (100/9.0)) )) 
     220    #for i in range(10): print(i, 0.001 + i*0.008/9.0) 
     221    #for i in range(100): print(i, int(math.floor( (i/ (100/9.0)) ))) 
    222222    out = Data2D() 
    223223    out.data = z 
     
    233233    value = Smearer2D(out,model,index).get_value() 
    234234    ## All data are ones, so the smeared values should also be ones. 
    235     print "Data length =",len(value), ", Data=",value 
    236 """ 
     235    print("Data length =",len(value), ", Data=",value) 
     236""" 
  • sasmodels/sasview_model.py

    rd138d43 r9404dd3  
    187187               for d in self._model.info['partype']['pd-2d'] 
    188188               for p in ('npts', 'nsigmas', 'width')] 
    189         #print ret 
     189        #print(ret) 
    190190        return ret 
    191191 
     
    303303            values, weights = self._dispersion_mesh() 
    304304            fv = ER(*values) 
    305             #print values[0].shape, weights.shape, fv.shape 
     305            #print(values[0].shape, weights.shape, fv.shape) 
    306306            return np.sum(weights * fv) / np.sum(weights) 
    307307 
Note: See TracChangeset for help on using the changeset viewer.