(file) Return to soshdata.py CVS log (file) (dir) Up to [Development] / JSOC / proj / globalhs / sosh

  1 tplarson 1.1 import numpy as np
  2              import os
  3              import drms
  4              from astropy.io import fits
  5              from urllib.request import urlretrieve
  6              import soundfile as sf
  7              
  8              import warnings 
  9              warnings.simplefilter(action='ignore', category=FutureWarning)
 10              
 11              #datadir = '/home/tplarson/solar/data'
 12              datadir = '../data'
 13              
 14 tplarson 1.2 def getmodeparms(instrument=None, day=None, lmin=0, lmax=300, makemsplit=True):
 15 tplarson 1.1 
 16                if not os.path.exists(datadir):
 17                  os.makedirs(datadir)
 18              
 19                if (instrument == None):
 20                  inst=input("Enter name of instrument: ")
 21                else:
 22                  inst=instrument
 23              
 24                if (day == None):
 25                  daystr=input("Enter day number: ")
 26                else:
 27                  daystr=str(day)
 28              
 29                mfile=getmfile(inst.lower(), daystr)
 30                if (mfile == None):
 31                  return None
 32              
 33 tplarson 1.2   if (makemsplit):
 34                  msfile=mfile+'.msplit'
 35 tplarson 1.1 
 36 tplarson 1.2     if os.path.exists(msfile):
 37                    print("Msplit file already exists.")
 38                  else:
 39                    msfile=mkmsplit(mfile,lmin=lmin,lmax=lmax)
 40              
 41                  return mfile,msfile
 42 tplarson 1.1   else:
 43 tplarson 1.2     return mfile
 44 tplarson 1.1 
 45              
 46              def getmfile(inst, daystr):
 47              
 48                if (inst == 'hmi'):
 49                  qblank = 'hmi.V_sht_modes[{:d}d][0][300][138240]'
 50                  mblank = 'hmi.%sd.modes'
 51                  avgurl = 'http://sun.stanford.edu/~tplarson/audio/HMI/hmi.average.modes'
 52                elif (inst == 'mdi'):
 53                  qblank = 'mdi.vw_V_sht_modes[{:d}d][0][300][103680]'
 54                  mblank = 'mdi.%sd.modes'
 55                  avgurl = 'http://sun.stanford.edu/~tplarson/audio/MDI/mdi.average.modes'
 56                else:
 57                  print("Invalid instrument, try again.")
 58                  return None
 59              
 60                mblank = '%s.%sd.modes'
 61                mfile=os.path.join(datadir,mblank % (inst, daystr))
 62                if os.path.exists(mfile):
 63                  print("Mode fits file already exists.")
 64                elif (daystr == 'average'):
 65 tplarson 1.1     try:
 66                    urlretrieve(avgurl, mfile)
 67                  except:
 68                    print("Failure of urlretrieve() for %s." % avgurl)
 69                    return None
 70                else:
 71                  try:
 72                    day=int(daystr)
 73                  except:
 74                      print("Invalid number, try again.")
 75                      return None
 76                  qstr=qblank.format(day)
 77                  c = drms.Client()
 78                  m = c.query(qstr, seg='m6')
 79                  if (len(m) == 0):
 80                    print("No data found for that day number, try again.")
 81                    return None
 82                  url = 'http://jsoc.stanford.edu' + m.m6[0]
 83                  try:
 84                    urlretrieve(url, mfile)
 85                  except:
 86 tplarson 1.1       print("Failure of urlretrieve() for %s." % url)
 87                    return None
 88              
 89                return mfile
 90              
 91              
 92              def mkmsplit(mfile, lmin=0, lmax=300):
 93              
 94                modeparms=np.loadtxt(mfile)
 95                lmod=modeparms[:,0]
 96                nmod=modeparms[:,1]
 97              
 98                outfmt='{:d} {:d} {:d} {:f} {:f}'
 99                outfile = mfile + '.msplit'
100                file=open(outfile,'w')
101              
102                l=lmin
103                while (l <= lmax):
104                  pols=apols(l,6)
105                  ind = (lmod == l)
106                  nlist = nmod[ind]
107 tplarson 1.1     for n in nlist:
108                    ind2 = (lmod == l) & (nmod == n)
109                    ai=np.append([0.0],modeparms[ind2,12:18]/1000)
110                    ei=np.append([0.0],modeparms[ind2,18:24]/1000)
111                    fx=np.matmul(pols,ai)
112                    freq=modeparms[ind2,2]+fx
113                    var=np.matmul((pols*pols),(ei*ei))
114                    sig=modeparms[ind2,7]+np.sqrt(var)
115                    for m in range(-l,l+1):
116                      outstr=outfmt.format(int(l),int(n),int(m),freq[m+l],sig[m+l])
117                      file.write('%s\n' % (outstr))
118                  l+=1
119                file.close()
120                return outfile
121              
122              
123              def getwavfiles(instrument=None, day=None, l=None, m=None, delfits=False):
124              
125                if not os.path.exists(datadir):
126                  os.makedirs(datadir)
127              
128 tplarson 1.1   if (instrument == None):
129                  inst=input("Enter name of instrument: ")
130                else:
131                  inst=instrument
132              
133                if (inst.lower() == 'hmi'):
134                  hind=1
135                elif (inst.lower() == 'mdi'):
136                  hind=0
137                else:
138                  print("Invalid instrument, try again.")
139                  return None
140              
141                if (day == None):
142                  daystr=input("Enter day number: ")
143                  try:
144                    day=int(daystr)
145                  except:
146                    print("Invalid number, try again.")
147                    return None
148                if (l == None):
149 tplarson 1.1     lstr=input("Enter spherical harmonic degree: ")
150                  try:
151                    l=int(lstr)
152                  except:
153                    print("Invalid number, try again.")
154                    return None
155                if (m == None):
156                  mstr=input("Enter azimuthal order: ")
157                  try:
158                    m=int(mstr)
159                    m=np.abs(m)
160                    if (m > l):
161                      print("Abs(m) must be less than l, try again.")
162                      return None
163                  except:
164                    print("Invalid number, try again.")
165                    return None
166              
167                wblank = '%s.%id_l=%i_m=%i_data%s.wav'
168                wfile=os.path.join(datadir,wblank % (inst.lower(),day,l,m,'r'))
169                wfile2=os.path.join(datadir,wblank % (inst.lower(),day,l,m,'i'))
170 tplarson 1.1   if os.path.exists(wfile) and (m==0 or os.path.exists(wfile2)):
171                  if (m == 0):
172                    print("Wav file already exists.")
173                    return wfile
174                  else:
175                    print("Wav files already exists.")
176                    return wfile,wfile2
177              
178                ffile=getfitsfile(inst.lower(),day,l)
179                if (ffile == None):
180                  return None
181              
182                wf=convertfitstowav(ffile, hind, m, wfile)
183                if (wf == None):
184                  return None
185              
186                if delfits:
187                  os.remove(ffile)
188                return wf
189              
190              
191 tplarson 1.1 def getfitsfile(inst, day, l):
192              
193                if (inst == 'hmi'):
194                  qblank = 'hmi.V_sht_gf_72d[{:d}d][{:d}][{:d}][138240]'
195                elif (inst == 'mdi'):
196                  qblank = 'mdi.vw_V_sht_gf_72d[{:d}d][{:d}][{:d}][103680]'
197                else:
198                  print("Invalid instrument, try again.")
199                  return None
200              
201                fblank='%s.%id.%i.fits'
202                ffile=os.path.join(datadir,fblank % (inst,day,l))
203                if os.path.exists(ffile):
204                  print("Fits file already exists.")
205                else:
206                  qstr=qblank.format(day,l,l)
207                  c = drms.Client()
208                  f = c.query(qstr,seg='data')
209                  if (len(f) == 0):
210                    print("No data found for that day number and degree, try again.")
211                    return None
212 tplarson 1.1     url = 'http://jsoc.stanford.edu' + f.data[0]
213                  try:
214                    urlretrieve(url, ffile)
215                  except:
216                    print("Failure of urlretrieve() for %s." % url)
217                    return None
218              
219                return ffile
220              
221              
222              def convertfitstowav(ffile, hind, m, wfile):
223              
224                hdul = fits.open(ffile)
225                h=hdul[hind]
226                d=h.data
227                x=d[m,0::2]/np.abs(d[m,:]).max()
228                sf.write(wfile, x, 8000, subtype='FLOAT')
229              
230                if (m > 0):
231                  wfile2=wfile.replace('datar','datai')
232                  x=d[m,1::2]/np.abs(d[m,:]).max()
233 tplarson 1.1     sf.write(wfile2, x, 8000, subtype='FLOAT')
234              
235                hdul.close()
236                if (m==0):
237                  return wfile
238                else:
239                  return wfile,wfile2
240              
241              
242              def apols(lin, amaxin):
243              
244              # adapted from IDL procedure apols.pro written by Jesper Schou
245              
246                l=np.long(lin)
247                amax=np.minimum(amaxin,2*l)
248              
249                pols=np.zeros((2*l+1,amaxin+1))
250              # It is ESSENTIAL that x is set up such that x(-m)=-x(m) to full machine
251              # accuracy or that the re-orthogonalization is done with respect to all
252              # previous polynomials (second option below).
253              # x=(dindgen(2*l+1)-l)/l
254 tplarson 1.1   x=np.linspace(-1,1,2*l+1)
255              
256                pols[:,0]=1/np.sqrt(2*l+1.0)
257                if (amax >= 1):
258                  pols[:,1]=x/np.sqrt((l+1.0)*(2*l+1.0)/(3.0*l))
259              # for n=2l,amax do begin
260              # Set up polynomials using exact recurrence relation.
261                for n in range(2,amax+1):
262                  a0=2.0*l*(2*n-1.0)/(n*(2*l-n+1))
263                  b0=-(n-1.0)/n*(2*l+n)/(2*l-n+1)
264                  a=a0*np.sqrt((2*n+1.0)/(2*n-1.0)*(2*l-n+1.0)/(2*l+n+1.0))
265                  b=b0*np.sqrt((2*n+1.0)/(2*n-3.0)*(2*l-n+1.0)*(2*l-n+2.0)/(2*l+n+1.0)/(2*l+n))
266                  help=a*x*pols[:,n-1]+b*pols[:,n-2]
267              # Turns out that roundoff kills the algorithm, so we have to re-orthogonalize.
268              # Two choices here. First one is twice as fast and more accurate, but
269              # depends on the rounding being done in the standard IEEE way.
270              #  for j=n-2,0,-2 do begin 
271                  for j in range(n-2,-1,-2):    
272              # This choice is robust to the roundoff, but twice as slow and generally
273              # somewhat less accurate
274              # for j=n-1,0,-1 do begin
275 tplarson 1.1       help=help-pols[:,j]*np.sum(help*pols[:,j])
276              #  end
277              # Reset norm to 1.
278                  pols[:,n]=help/np.sqrt(np.sum(np.square(help)))
279              
280              # Reset polynomials to have P_l(l)=l by setting overall norm.
281              # Note that this results in more accurate overall normalization, but
282              # that P_l(l) may be very far from l. This is the key to the algorithm.
283                c=l**2*(2*l+1.0)
284              # for n=0l,amax do begin
285                for n in range(0,amax+1):
286                  c=c*(2*l+n+1.0)/(2*l-n+1.0)
287                  pols[:,n]=pols[:,n]*np.sqrt(c/(2*n+1))
288              
289                return pols
290              
291              

Karen Tian
Powered by
ViewCVS 0.9.4