Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- """
- Created on Sun Nov 03 20:32:01 2013
- INSTRUCTIONS
- ~~~~~~~~~~~~
- This is a template file for you to use for your Computing 2 Coursework.
- Save this file as py12spqr.py when py12spqr should be replaced with your ISS username
- Do not rename or remove the function ProcessData, the marking will assume that this function exists
- and will take in the name of a data file to open and process. It will assume that the function will return
- all the answers your code finds. The results are returned as a dictionary.
- Your code should also produce the same plot as you produce in your report.
- @author: phygbu
- """
- def ProcessData(filename):
- try:
- Metadata = GetData(filename)[0]
- xdata = GetData(filename)[1]
- ydata = GetData(filename)[2]
- FullPlot(xdata, ydata, "Magnetic Field (A/m)", "Absorption (arb units)", "py13kb Results for 20GHz", "ro", "m")
- Peakat = ((Lorfit(xdata, ydata))[0])[0]
- Peakwid = ((Lorfit(xdata, ydata))[0])[1]
- except ValueError or NameError or Exception:
- print "Something went horribly wrong"
- sys.exit()
- results={"20GHz_peak":None, #this would be the peak position at 20GHz
- "20GHz_width": None, #Delta H for 20 GHz
- "gamma": None, #your gamma value
- "g": None, #Your Lande g factor
- "Hk": None, #Your value for the anisotropy field
- "Ms": None, #Your value for trhe sauration Magnetisation
- "DeltaH": None, #Your value ffor the intrinsic line width
- "alpha": None }# Your value for the Gilbert Damping parameter
- results["20GHz_peak"] = Peakat
- results["20GHz_width"] = Peakwid
- #If your code doesn't find all of these values, just leave them set to None
- #Otherwise return the number. Your report should also give the errors in these numbers.
- return results
- if __name__=="__main__":
- import math
- from math import sqrt
- import numpy as np
- from numpy import diag
- from itertools import ifilter as Filt
- import matplotlib.pyplot as plt
- from scipy.optimize import curve_fit
- import sys
- def GetData(Filename):
- #Will make sure that the file names are correct, and display a message if they are not
- try:
- with open(Filename, "r") as Datafile:
- Metadataprep = Filt(lambda x: x[0:3].isdigit() == False and x[0:3] != "0.0", Datafile) #filters out all the lines that are exclusively numeric data
- Metadata = np.genfromtxt(Metadataprep, delimiter="\t", #reads the non-numeric data into an array
- autostrip=True, #I have done it this way in case the metadata messes up and doesn't put in the "&END" or somesuch, even though it is more cumbersome
- skip_footer=1,
- dtype = str
- )
- while Metadata[0] == "&SRS" or Metadata[0] == "<MetaDataAtStart>":
- Metadata = np.delete(Metadata, [0]) #Trimms off the metadata and SRS for neatness' sake, though there must be a better way to do this
- Metadata = Metadata[::-1]
- while Metadata[0] == "&END" or Metadata[0] == "</MetaDataAtStart>":
- Metadata = np.delete(Metadata, [0])
- Metadata = Metadata[::-1] # Finally finished trimming
- with open(Filename, "r") as Datafile:
- Dataprep = Filt(lambda x: x[0:3].isdigit() or x[0:3] == "0.0", Datafile) #filters out all the lines that are not exclusively numeric data within reason
- Data = np.genfromtxt(Dataprep, delimiter="\t", #reads the numeric data into an array
- autostrip=True,
- )
- xdata = Data[:,0] #Assigning the data to the final names to be returned
- ydata = Data[:,1] #Worth noting that by putting a ":" after the 1 here, the Plotme function will work for multiple frequencies, but fitting is not coded to accomodate this
- return Metadata, xdata, ydata
- except Exception or NameError:
- print "An error has occured retrieving the file"
- def Plotme(Xdata, Ydata, XAxisLabel, YAxisLabel, Title): #Basic plotting function, input your data and it'll plot for you
- plt.plot(Xdata, Ydata)
- plt.title(Title)
- plt.ylabel(YAxisLabel)
- plt.xlabel(XAxisLabel)
- plt.show()
- def FPlotme(Xdata, Ydata, Yfit, XAxisLabel, YAxisLabel, Title, Col1, Col2): #Specific plotting function designed to be called by FullPlot, but usable itself
- plt.plot(Xdata, Ydata, Col1,\
- Xdata, Yfit, Col2)
- plt.title(Title)
- plt.ylabel(YAxisLabel)
- plt.xlabel(XAxisLabel)
- def lorentz(xdata, peak, peakwid, K): #Lorentx function for fitting purposes
- y = (float(K)*0.5*math.pi) * (float(peakwid) / ((xdata - float(peak))**2 + (float(peakwid)/2)**2)) #The floats are important or it evaluates to zero midway
- return y
- def Lorfit(x, y): #fits x and y using the lorentzian function, returns an array of Values for the Peak, Peakwidth and K factor, and then an array for the covariance matrix
- LorValues, LorErr=curve_fit(lorentz, x, y, p0=[300000, 20000, 80000]) #the guesses are based on the 20GHz data, but don't matter much
- return LorValues, LorErr
- def Annotate(): #Annotation function that when working with Lorfit will produce annotations for a plot, giving you the Peak, Peak Width, and K factor
- Peakanno1 = "Peak at " + str((Lorfit(xdata, ydata)[0])[0]) + " +- " + str(GetError(xdata, ydata, 0))
- Peakanno2 = "Peak width is " + str((Lorfit(xdata, ydata)[0])[1]) + " +- " + str(GetError(xdata, ydata, 1))
- Peakanno3 = "K factor is " + str((Lorfit(xdata, ydata)[0])[2]) + " +- " + str(GetError(xdata, ydata, 2))
- Peak = (Lorfit(xdata, ydata)[0])[0]
- plt.annotate(Peakanno1, xy=(Peak, ydata.max()),
- xytext = (30, -20), textcoords = 'offset points',
- arrowprops = dict(arrowstyle="->"))
- plt.annotate(Peakanno2, xy=(Peak, ydata.max()),
- xytext = (30, -40), textcoords = 'offset points')
- plt.annotate(Peakanno3, xy=(Peak, ydata.max()),
- xytext = (30, -60), textcoords = 'offset points')
- def FullPlot(X, Y, Xax, Yax, Title, Col1, Col2): #A Function that will return a full plot including the fitting analysis and annotations
- Lorfit(X, Y)
- Yfit = lorentz(X, (Lorfit(X, Y)[0])[0], (Lorfit(X, Y)[0])[1], (Lorfit(X, Y)[0])[2])
- FPlotme(X, Y, Yfit, Xax, Yax, Title, Col1, Col2)
- Annotate()
- plt.show()
- def GetError(xdata, ydata, n): #Uses LorFit to grab the covariance matrix and reads out the nth Lorfit value's error
- Error = sqrt(((Lorfit(xdata, ydata))[1])[n,n])
- return Error
- filename="My Data File.txt"
- test_results=ProcessData(filename)
- print test_results
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement