| Conditions | 17 |
| Total Lines | 205 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like ne_spiral_arm() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
| 1 | """ Density for spiral arms |
||
| 11 | def ne_spiral_arm(xyz, gal_param, adict): |
||
| 12 | """ |
||
| 13 | Parameters |
||
| 14 | ---------- |
||
| 15 | xyz |
||
| 16 | gal_param |
||
| 17 | adict |
||
| 18 | |||
| 19 | Returns |
||
| 20 | ------- |
||
| 21 | nea : ndarray or float |
||
| 22 | whicharm : ndarray or int |
||
| 23 | |||
| 24 | c----------------------------------------------------------------------- |
||
| 25 | c Spiral arms are defined as logarithmic spirals using the |
||
| 26 | c parameterization in Wainscoat et al. 1992, ApJS, 83, 111-146. |
||
| 27 | c But arms are modified selectively at various places to distort them |
||
| 28 | c as needed (08 Aug 2000). |
||
| 29 | c Note that arm numbering follows that of TC93 for the four large arms |
||
| 30 | c (after remapping). |
||
| 31 | c The local spiral arm is number 5. |
||
| 32 | c 06 Apr 02: removed TC type modifications of arms 2,3 (fac calculations) |
||
| 33 | c and replaced with new versions. Data for these are hard wired. |
||
| 34 | """ |
||
| 35 | from scipy.interpolate import CubicSpline |
||
| 36 | x,y,z = xyz[0], xyz[1], xyz[-1] |
||
| 37 | if isinstance(x,float): |
||
| 38 | x = np.array([x]) |
||
| 39 | y = np.array([y]) |
||
| 40 | z = np.array([z]) |
||
| 41 | flg_float = True |
||
| 42 | else: |
||
| 43 | flg_float = False |
||
| 44 | |||
| 45 | # see get_parameters for definitions of narm, warm, harm. |
||
| 46 | narmsmax=5 |
||
| 47 | #common/armfactors/ |
||
| 48 | # . harm(narmsmax),narm(narmsmax),warm(narmsmax),farm(narmsmax) |
||
| 49 | |||
| 50 | # parameter(rad=57.29577 95130 823) |
||
| 51 | rad = 180/np.pi |
||
| 52 | ks=3 |
||
| 53 | NN=7 |
||
| 54 | nfine = 1000 |
||
| 55 | |||
| 56 | # rr |
||
| 57 | rr = rad2d2(xyz) |
||
| 58 | if flg_float: |
||
| 59 | rr = np.array([rr]) |
||
| 60 | |||
| 61 | #c |
||
| 62 | #c Get spiral arm component: 30 do loop finds a coarse minimum distance |
||
| 63 | #c from line of sight to arm; 40 do loop finds a fine minimum distance |
||
| 64 | #c from line of sight to arm; line 35 ensures that arm limits are not |
||
| 65 | #c exceeded; linear interpolation beginning at line 41 finds the |
||
| 66 | #c minimum distance from line of sight to arm on a finer scale than gridding |
||
| 67 | #c of arms allows (TJL) |
||
| 68 | |||
| 69 | # Init |
||
| 70 | whicharm = np.zeros_like(x).astype(int) |
||
| 71 | nea = np.zeros_like(x) |
||
| 72 | |||
| 73 | # thxy |
||
| 74 | thxy = np.arctan2(-x, y) * rad #! measured ccw from +y axis |
||
| 75 | #! (different from tc93 theta) |
||
| 76 | neg_th = thxy < 0. |
||
| 77 | thxy[neg_th] += 360. |
||
| 78 | # Cut on values near the disk |
||
| 79 | icutz = np.where(np.abs(z/gal_param['ha']) < 10.)[0] |
||
| 80 | if len(icutz) > 0: |
||
| 81 | cutx = x[icutz] |
||
| 82 | cuty = y[icutz] |
||
| 83 | cutz = z[icutz] |
||
| 84 | sminmin = 1.e10 * np.ones_like(cutx) |
||
| 85 | else: |
||
| 86 | # Time to return |
||
| 87 | return nea |
||
| 88 | # Find closest distance to each arm and then assign arm |
||
| 89 | # We will brute force with a spline |
||
| 90 | # Could get memory intensive |
||
| 91 | # Could refine |
||
| 92 | for j in range(adict['narms']): |
||
| 93 | #do 50 j=1,narms |
||
| 94 | jj = adict['armmap'][j] |
||
| 95 | # Crude |
||
| 96 | xarm = adict['arm'][j,:adict['kmax'][j],0] |
||
| 97 | yarm = adict['arm'][j,:adict['kmax'][j],1] |
||
| 98 | |||
| 99 | xtmp = np.outer(cutx, np.ones_like(xarm)) |
||
| 100 | ytmp = np.outer(cuty, np.ones_like(yarm)) |
||
| 101 | xatmp = np.outer(np.ones_like(cutx), xarm) |
||
| 102 | yatmp = np.outer(np.ones_like(cuty), yarm) |
||
| 103 | dist = (xtmp-xatmp)**2 + (ytmp-yatmp)**2 |
||
| 104 | kmin = np.argmin(dist,axis=1) |
||
| 105 | |||
| 106 | # Refine with a Spline? -- Requires a loop |
||
| 107 | csp_xarm = CubicSpline(np.arange(adict['kmax'][j]), |
||
| 108 | adict['arm'][j,:adict['kmax'][j],0]) |
||
| 109 | csp_yarm = CubicSpline(np.arange(adict['kmax'][j]), |
||
| 110 | adict['arm'][j,:adict['kmax'][j],1]) |
||
| 111 | jtmp = np.zeros((len(cutx),nfine)) |
||
| 112 | for ii,ix in enumerate(cutx): |
||
| 113 | j0 = max(0, kmin[ii]-1) |
||
| 114 | j1 = min(adict['kmax'][j], kmin[ii]+1) |
||
| 115 | jtmp[ii,:] = np.linspace(j0,j1,num=nfine) |
||
| 116 | xjarm = csp_xarm(jtmp) |
||
| 117 | yjarm = csp_yarm(jtmp) |
||
| 118 | xtmp = np.outer(cutx, np.ones(nfine)) |
||
| 119 | ytmp = np.outer(cuty, np.ones(nfine)) |
||
| 120 | dist = (xtmp-xjarm)**2 + (ytmp-yjarm)**2 |
||
| 121 | kmin2 = np.argmin(dist,axis=1) |
||
| 122 | min_dist2 = np.amin(dist,axis=1) |
||
| 123 | |||
| 124 | # |
||
| 125 | smin=np.sqrt(min_dist2) # ! Distance of (x,y,z) from this arm's axis |
||
| 126 | # Close enough? |
||
| 127 | gd_wa = np.where(smin < (3*gal_param['wa']))[0] |
||
| 128 | if len(gd_wa) > 0: |
||
| 129 | # ga |
||
| 130 | ga = np.exp(-(smin[gd_wa]/( |
||
| 131 | gal_param['warm{:d}'.format(jj)]*gal_param['wa']))**2) #! arm, get the arm weighting factor |
||
| 132 | # Galactocentric radial dependence of arms |
||
| 133 | tmp_rr = rr[icutz[gd_wa]] |
||
| 134 | lg_rr = tmp_rr > gal_param['Aa'] |
||
| 135 | if np.sum(lg_rr) > 0: |
||
| 136 | ga[lg_rr] *= 1. / (np.cosh((tmp_rr[lg_rr]-gal_param['Aa'])/2.0))**2 |
||
| 137 | |||
| 138 | # arm3 reweighting: |
||
| 139 | if adict['armmap'][j] == 3: |
||
| 140 | th3a=320. |
||
| 141 | th3b=390. |
||
| 142 | th3b=370. |
||
| 143 | th3a=290. |
||
| 144 | th3b=363. |
||
| 145 | th3b=363. |
||
| 146 | fac3min=0.0 |
||
| 147 | test3 = thxy[icutz[gd_wa]]-th3a |
||
| 148 | neg_t3 = test3 < 0 |
||
| 149 | test3[neg_t3] += 360. |
||
| 150 | gd_t3 = (0. <= test3) & (test3 < (th3b-th3a)) |
||
| 151 | if np.sum(gd_t3) > 0: |
||
| 152 | arg = 6.2831853*(thxy[icutz[gd_wa]][gd_t3]-th3a)/(th3b-th3a) |
||
| 153 | fac = (1.+fac3min + (1.-fac3min)*np.cos(arg))/2. |
||
| 154 | fac = fac**4.0 |
||
| 155 | # Update ga |
||
| 156 | ga[gd_t3] *= fac |
||
| 157 | |||
| 158 | # arm2 reweighting: |
||
| 159 | if adict['armmap'][j] == 2: |
||
| 160 | th2a=35. |
||
| 161 | th2b=55. |
||
| 162 | test2 = thxy[icutz[gd_wa]]-th2a |
||
| 163 | fac = 1. |
||
| 164 | if False: |
||
| 165 | # first: as in tc93 (note different definition of theta) |
||
| 166 | gd_t2_first = (0 <= test2) & (test2 < (th2b-th2a)) |
||
| 167 | if np.sum(gd_t2_first) > 0: |
||
| 168 | fac=1.+ test2[gd_t2_first]/(th2b-th2a) |
||
| 169 | fac = 1. # !**** note turned off |
||
| 170 | #ga=ga*fac |
||
| 171 | gd_t2_first2 = test2 > (th2b-th2a) |
||
| 172 | if np.sum(gd_t2_first2) > 0: |
||
| 173 | fac = 2. |
||
| 174 | fac = 1. #!**** note turned off |
||
| 175 | #ga=ga*fac |
||
| 176 | # c second: weaken the arm in a short range: |
||
| 177 | th2a=340. |
||
| 178 | th2b=370. |
||
| 179 | # c note fix does nothing if fac2min = 1.0 |
||
| 180 | fac2min=0.1 |
||
| 181 | neg_t2 = test2 < 0. |
||
| 182 | test2[neg_t2] += 360. |
||
| 183 | gd_t2_snd = (0. <= test2) & (test2 < (th2b-th2a)) |
||
| 184 | if np.sum(gd_t2_snd) > 0: |
||
| 185 | arg=6.2831853*(thxy[icutz[gd_wa]][gd_t2_snd]-th2a)/(th2b-th2a) |
||
| 186 | fac = (1.+fac2min + (1.-fac2min)*np.cos(arg))/2. |
||
| 187 | # Update ga |
||
| 188 | ga[gd_t2_snd] *= fac |
||
| 189 | |||
| 190 | # Find the ones which are closer than any previous arm |
||
| 191 | iclosest = smin[gd_wa] < sminmin[gd_wa] |
||
| 192 | if np.sum(iclosest) > 0: |
||
| 193 | whicharm[icutz[gd_wa[iclosest]]] = adict['armmap'][j] |
||
| 194 | |||
| 195 | # Update nea |
||
| 196 | nea[icutz[gd_wa]] += gal_param['narm{:d}'.format(jj)] * gal_param['na'] * ( |
||
| 197 | ga / (np.cosh(cutz[gd_wa]/(gal_param['harm{:d}'.format(jj)]*gal_param['ha']))**2)) |
||
| 198 | if flg_float: |
||
| 199 | nea = float(nea[0]) |
||
| 200 | whicharm = int(whicharm[0]) |
||
| 201 | |||
| 202 | # Return |
||
| 203 | return nea # , whicharm |
||
| 204 | |||
| 205 | ''' |
||
| 206 | Farms = 0 |
||
| 207 | if(whicharm_spiralmodel .eq. 0) then |
||
| 208 | whicharm = 0 |
||
| 209 | else |
||
| 210 | whicharm = armmap(whicharm_spiralmodel) ! remap arm number |
||
| 211 | Farms = Fa * farm(whicharm) |
||
| 212 | endif |
||
| 213 | return |
||
| 214 | end |
||
| 215 | ''' |
||
| 216 |