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

Karen Tian
Powered by
ViewCVS 0.9.4