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

Karen Tian
Powered by
ViewCVS 0.9.4