pro norh_gysy_inv,fi0,fi1 $
  ,delta,fv0,arg3,arg4,arg5,omega,tau $
  ,freq0=freq0,freq1=freq1,mvalid=mvalid $
  ,assumetheta=assumetheta,assumebb=assumebb,assumenv=assumenv

;+
; NAME:
;       norh_gysy_inv
;
; PURPOSE:
;       Derive physical variables from a set of NoRH flux (17GHz-I, 
;       17GHz-V, 34GHz-I) based on the assumption that the emssion is of
;       gyrosyncrotron radiation from power-law electrons.
;         (c.f.  Dulk, 1985, ARAA, 23, 169)
;
; CALLING SEQUENCE:
;     Assume  power law,
;          dNV(E)/dE = K(E0) (E/E0)^(-delta) where E0=10keV
;               where K(E0) = NV(E0)*(delta-1)*E0^(delta-1)
;        NV(E)  : total number of non-thermal e- over energy E [particles] 
;        B : magnetic field strength
;        theta : angle [degree] between Line-of-sight and magnetic vector
;        tau   : Optical thickness
;
;     (0) get delta without any assumption
;       norh_gysy_inv,fi0,fi1,delta
;
;     (1) get delta, B, and NV by assuming theta
;       norh_gysy_inv,fi0,fi1,delta,fv0,thetain,bb,nv,/assumetheta
;
;     (2) get delta, NV, and theta by assuming B
;       norh_gysy_inv,fi0,fi1,delta,fv0,bbin,nv,theta,/assumebb
;
;     (3) get delta, theta and B by assuming NV
;       norh_gysy_inv,fi0,fi1,delta,fv0,nvin,theta,bb,/assumenv
;
;     (4) get delta, B, NV and tau by assuming theta and omega
;       norh_gysy_inv,fi0,fi1,delta,fv0,thetain,bb,nv,/assumetheta,omega,tau
;
;     (5) get delta, NV, theta, and tau by assuming B and omega
;       norh_gysy_inv,fi0,fi1,delta,fv0,bbin,nv,theta,/assumebb,omega,tau
;
;     (6) get delta, theta, B and tau by assuming NV and omega
;       norh_gysy_inv,fi0,fi1,delta,fv0,nvin,theta,bb,/assumenv,omega,tau
;
; INPUTS:
;       fi0: flux density [SFU] of Stokes-I(r+l) component at frequency #0.
;       fi1: flux density [SFU] of Stokes-I(r+l) component at frequency #1.
;       fv0: flux density [SFU] of Stokes-V(r-l) component at frequency #0.
;       thetain: assumed angle [degree] 
;                 between Line-of-sight and magnetic vector
;       bbin: assumed magnetic field strength [G]
;       nvin: assumed total number of non-thermal e- [particles]
;       omega: source size in surface angle [steradian]
;
; OUTPUTS:
;       delta: power-law index of non-thermal e- distribution
;       theta: angle [degree] between Line-of-sight and magnetic vector
;       bb: magnetic field strength [G]
;       nv: total number of non-thermal e- [particles]
;
; OPTIONAL INPUTS:
;      freq0: frequency #0 [GHz]. Default is 17GHz.
;      freq1: frequency #1 [GHz]. Default is 34GHz.
;
; OPTIONAL OUTPUTS:
;      mvalid  ;  1 if valid data, 0 if invalid data
;
; HISTORY:
;       Writtern 1999-09-08 T. Yokoyama
;       Revised  2000-05-03 T. Yokoyama bug fix
;
;-


if (not keyword_set(freq0)) then freq0 = 17.
if (not keyword_set(freq1)) then freq1 = 34.

freq00=freq0*1.e9
freq10=freq1*1.e9

mvalid=byte(fi0) & mvalid(*)=1b

rfreq=freq10/freq00
rf = fi1/fi0

delta=(1.2-alog10(rf)/alog10(rfreq))/0.895 

if (n_params() eq 3) then return  

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Derive physical variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Universal constant

c = 3e10         ; [cm/s] speed of light
kb = 1.38*10.^(-16)  ; [cgs] Bolzmann constant
cm2_per_omega = (7.e7/(!dtor/3600.))^2
cgs2sfu = 1.e19 ; SFU/[erg/s/cm^2/Hz]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if keyword_set(assumetheta) then begin

thetain=arg3
sint = sin(thetain*!dtor)
cost = cos(thetain*!dtor)

rc = fv0/fi0

rclim=1.e-3   ; S/N limit
whr=where((abs(rc) lt rclim),count)
if (count ge 1) then mvalid(whr)=0b

;    rc -> B   from eq(38)
;
xi = -0.782+0.545*cost
fratio = ( abs(rc) /( 1.26 * 10.^(0.035*delta-0.071*cost) ) )^(1/xi)

whr=where((fratio lt 10) or (fratio gt 100),count) ; Dulk's approxmation limit
if (count ge 1) then mvalid(whr)=0b
fratio0=(fratio<100)>10

fgyro = freq00/fratio0
bb = fgyro/2.8e6

;    Fi -> NV
;
teeff = 2.2e9 * 10.^(-0.31*delta) * (sint)^(-0.36-0.06*delta) $
         * fratio0^(0.50+0.085*delta)
tau_over_nl = 1.4*10.^(-9) * 10.^(-0.22*delta) * (sint)^(-0.09+0.72*delta) $
         * fratio0^(-1.3-0.98*delta) /bb
teb_over_nl = teeff * tau_over_nl
fi_over_nlomega = double(kb*freq00^2/c^2 *teb_over_nl*2)
ficgs= fi0 /cgs2sfu
nlomega = double(ficgs)/double(fi_over_nlomega)
nv = nlomega * cm2_per_omega

arg4 = bb
arg5 = nv

endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

if keyword_set(assumebb) then begin

bbin=arg3
rc = fv0/fi0

rclim=1.e-3   ; S/N limit
whr=where((abs(rc) lt rclim),count)
if (count ge 1) then mvalid(whr)=0b

;    rc -> theta   from eq(38)
;
fgyro = bbin * 2.8e6
fratio= freq00/fgyro

; Dulk's approxmation limit
if (fratio gt 100) then begin
  print,'% Warning : assumed B strength too weak'
  print,'%    It should be between ',freq00/100./2.8e6, $
    ' and ',freq00/10./2.8e6,' G'
endif
if (fratio lt 10) then begin
  print,'% Warning : assumed B strength too strong'
  print,'%    It should be between ',freq00/100./2.8e6, $
    ' and ',freq00/10./2.8e6,' G'
endif
cost = (alog10(1.26)+0.035*delta-0.782*alog10(fratio)-alog10(abs(rc)>rclim)) $
       / (0.071-0.545*alog10(fratio))

costlim0=0.0000   ; Dulk's approxmation limit
costlim1=0.9400   ; abs(cos(20 degree)) Dulk's approxmation limit
whr=where((cost gt costlim1) or (cost lt costlim0),count)
if (count ge 1) then mvalid(whr)=0b
cost0=(cost<costlim1)>(costlim0)

theta = acos(cost0) * !radeg
sint = sqrt(1 - cost0^2)

;    Fi -> NV
;
teeff = 2.2e9 * 10.^(-0.31*delta) * (sint)^(-0.36-0.06*delta) $
         * fratio^(0.50+0.085*delta)
tau_over_nl = 1.4*10.^(-9) * 10.^(-0.22*delta) * (sint)^(-0.09+0.72*delta) $
         * fratio^(-1.3-0.98*delta) /bbin
teb_over_nl = teeff * tau_over_nl
fi_over_nlomega = double(kb*freq00^2/c^2 *teb_over_nl)
ficgs= fi0 /cgs2sfu
nlomega = double(ficgs)/double(fi_over_nlomega)
nv = nlomega * cm2_per_omega

arg4 = nv
arg5 = theta

endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if keyword_set(assumenv) then begin
  print,'This option is not yet supported'
  return
endif

if (n_params() eq 7) then return  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  nl = nlomega / omega
  tau = tau_over_nl * nl

return
end
