|
| 1 | + |
| 2 | + |
| 3 | +// ------------------------------------------------------------------------------- |
| 4 | +// ------------------------------------------------------------------------------- |
| 5 | + |
| 6 | +// Main function |
| 7 | +// Example : |
| 8 | +// gen_C0_C1 ( x_wavenumber, 632.8 , root:whitelight , 670 , maskWave = mask1D ) |
| 9 | +// wave laser_nm wave pixel maskWave |
| 10 | + |
| 11 | +// returns : intensity_corr : 1D wave which corresponds to (C0/C1), to be multiplied to the Raman spectra. |
| 12 | + |
| 13 | +function gen_C0_C1 ( ramanshift , laser_nm , wl_wave , norm_pnt , [ maskWave , set_mask_nan] ) |
| 14 | + |
| 15 | + wave ramanshift // relative, vector |
| 16 | + variable laser_nm // laser wavelength, nm, scalar |
| 17 | + wave wl_wave // white_light spectra, un-normalized, 1D or 2D, vector |
| 18 | + variable norm_pnt // normalization index, pnt, scalar |
| 19 | + |
| 20 | + wave maskWave // optional, supply mask for wl fitting , for eg. maskWave = mask_1D, vector |
| 21 | + variable set_mask_nan // optional, 0 or 1. When set to 1, the masked region is set to nan in the output |
| 22 | + // intensity_corr wave. When set to 0, intensity_corr wave is not modified for the mask |
| 23 | + // region. |
| 24 | + |
| 25 | + variable nPnts = dimsize(ramanshift, 0) |
| 26 | + variable mid = nPnts/2 |
| 27 | + |
| 28 | + |
| 29 | + // initialization |
| 30 | + killwaves /Z W_coef, W_ParamConfidenceInterval, W_sigma, fit |
| 31 | + |
| 32 | + // generate the C0 correction |
| 33 | + gen_C0(ramanshift , norm_pnt) |
| 34 | + wave C0 |
| 35 | + |
| 36 | + // wl spectra (check averaging) |
| 37 | + variable nCols_wl = dimsize(wl_wave,1) |
| 38 | + if (nCols_wl > 1) |
| 39 | + print "\twl_wave is 2D. Averaging.\r" |
| 40 | + do_average_custom(wl_wave) |
| 41 | + string newWave= nameofwave(wl_wave)+"_avg" |
| 42 | + printf "\tAveraged wave : %s\r", newWave |
| 43 | + wave wl_wave = $newWave |
| 44 | + endif |
| 45 | + |
| 46 | + // wl spectra (normalization) and multiply with C0 |
| 47 | + make /d /o /n=(nPnts) wl_norm = wl_wave/ wavemax(wl_wave) |
| 48 | + wl_norm=wl_norm*C0 |
| 49 | + wave wl_norm |
| 50 | + |
| 51 | + // wl spectra (subset) |
| 52 | + variable result // returned value is assigned to result |
| 53 | + |
| 54 | + // Determine if the optional parameters were supplied |
| 55 | + if( ParamIsDefault(maskWave) ) |
| 56 | + |
| 57 | + print "\t Mask wave not supplied. Working with full wave.\r" |
| 58 | + result = gen_C1(ramanshift, laser_nm , wl_norm , norm_pnt) |
| 59 | + |
| 60 | + elseif ( waveExists ( maskWave )) |
| 61 | + print "\tMask wave is supplied. Using it for fit.\r" |
| 62 | + result = gen_C1_mask (ramanshift, laser_nm , wl_norm , norm_pnt , maskWave) |
| 63 | + endif |
| 64 | + |
| 65 | + |
| 66 | + //-------------------------------------------------------------- |
| 67 | + // wave references (C0 and C1 should exist in present folder) |
| 68 | + wave C0 |
| 69 | + wave C1 |
| 70 | + //-------------------------------------------------------------- |
| 71 | + |
| 72 | + if (result ==2 ) |
| 73 | + |
| 74 | + if (set_mask_nan == 1) |
| 75 | + printf "\n\n\tset_mask_nan parameter is set to 1. Masked region in the intensity corr will be set to Nan.\r" |
| 76 | + |
| 77 | + wave C1_out = set_nan_correspond_to_mask (C1, maskWave) |
| 78 | + wave C1= C1_out |
| 79 | + else |
| 80 | + printf "\n\n\tset_mask_nan parameter not set to 1.\r" |
| 81 | + endif |
| 82 | + endif |
| 83 | + //-------------------------------------------------------------- |
| 84 | + make /d /o /n=(nPnts) intensity_corr = (C0/C1) |
| 85 | + |
| 86 | + printf "\n\tintensity_corr generated. Done. This is equal to (C0/C1)\r" |
| 87 | + |
| 88 | + // cleanup |
| 89 | + killwaves /Z abs_wavenumber_subset, wl_norm_subset, W_coef, fit, coefs |
| 90 | + killwaves /Z W_ParamConfidenceInterval, W_sigma |
| 91 | + |
| 92 | +end |
| 93 | + |
| 94 | + |
| 95 | +// ------------------------------------------------------------------------------- |
| 96 | +// ------------------------------------------------------------------------------- |
| 97 | + |
| 98 | +STATIC function gen_C0(ramanshift , norm_pnt) |
| 99 | + |
| 100 | + wave ramanshift // relative |
| 101 | + variable norm_pnt // normalization index, pnt |
| 102 | + |
| 103 | + variable nPnts = dimsize(ramanshift, 0) |
| 104 | + variable mid = nPnts/2 |
| 105 | + |
| 106 | + make /FREE /o /n=(nPnts-1) wavenumber_spacing =0 |
| 107 | + wavenumber_spacing = ramanshift [p] - ramanshift [p+1] |
| 108 | + |
| 109 | + // normalization |
| 110 | + make /d /o /n=(nPnts-1) waveum_corr = ( wavenumber_spacing / wavenumber_spacing [ norm_pnt ]) |
| 111 | + make /FREE /d /n=(nPnts-1) xax=p |
| 112 | + // ------------------------ |
| 113 | + |
| 114 | + // computing the value at the last point |
| 115 | + CurveFit /Q poly 3, waveum_corr /X=xax |
| 116 | + wave W_coef |
| 117 | + variable val_plus1_pnt = poly(W_coef, nPnts-1 ) |
| 118 | + //print val_plus1_pnt |
| 119 | + |
| 120 | + InsertPoints (nPnts-1),1, waveum_corr |
| 121 | + waveum_corr [nPnts-1] = val_plus1_pnt |
| 122 | + |
| 123 | + duplicate /O waveum_corr, C0 |
| 124 | + |
| 125 | + killwaves /Z wavenum_corr |
| 126 | + |
| 127 | + |
| 128 | +end |
| 129 | + |
| 130 | +// ------------------------------------------------------------------------------- |
| 131 | +// ------------------------------------------------------------------------------- |
| 132 | + |
| 133 | +STATIC function gen_C1(ramanshift, laser_nm , wl_input norm_pnt) |
| 134 | + |
| 135 | + wave ramanshift // relative |
| 136 | + variable laser_nm // laser wavelength (nm) |
| 137 | + wave wl_input // normalized wl wave with C0 multiplied |
| 138 | + variable norm_pnt // normalization index, pnt |
| 139 | + |
| 140 | + variable nPnts = dimsize(ramanshift, 0) |
| 141 | + variable mid = nPnts/2 |
| 142 | + |
| 143 | + |
| 144 | + // cleanup from prev run |
| 145 | + killwindow /Z genC0C1 |
| 146 | + |
| 147 | + // make abs_wavenumber, for xaxis |
| 148 | + |
| 149 | + make /o /d /n=(nPnts) abs_wavenumber = ((1e7/laser_nm)-ramanshift)*100 |
| 150 | + make /o /d /n=2 coefs |
| 151 | + |
| 152 | + // defining initial coefs |
| 153 | + coefs[0] = 0.856e-18 |
| 154 | + coefs[1] = 2759 // 0.856e-18 |
| 155 | + |
| 156 | + |
| 157 | + Display /K=1 wl_input vs abs_wavenumber |
| 158 | + FuncFit photons_per_unit_wavenum_abs coefs wl_input /X=abs_wavenumber |
| 159 | + |
| 160 | + printf "\tFit (not using mask), Obtained fit coef:%5.6e, %5.6e",coefs[0],coefs[1] |
| 161 | + |
| 162 | + make /o /d /n=(nPnts) fit = photons_per_unit_wavenum_abs(coefs,abs_wavenumber) |
| 163 | + appendtograph fit vs abs_wavenumber |
| 164 | + |
| 165 | + // customize graph |
| 166 | + ModifyGraph grid=1,mirror=1,axThick=1.2,lblPosMode(bottom)=2;DelayUpdate |
| 167 | + ModifyGraph lblMargin(bottom)=2,gridHair=1,manTick(left)={0,0.1,0,1},manMinor(left)={3,2},manTick(bottom)={0,0.02,6,2} |
| 168 | + ModifyGraph manMinor(bottom)={3,2},gridRGB(left)=(13107,13107,13107),gridRGB(bottom)=(17476,17476,17476); |
| 169 | + Label left "Intensity";DelayUpdate |
| 170 | + Label bottom "Wavenumber / m\\S-1" |
| 171 | + ModifyGraph fSize=25 |
| 172 | + ModifyGraph rgb(fit)=(0,0,65535) |
| 173 | + ModifyGraph lsize=2 |
| 174 | + SetAxis left 0,* |
| 175 | + DoUpdate; |
| 176 | + |
| 177 | + // generate C1 |
| 178 | + make /o /d /n=(nPnts) C1 = wl_input / fit |
| 179 | + |
| 180 | + // remove fit and residual wave |
| 181 | + string fname="fit_"+nameofwave(wl_input) |
| 182 | + killwaves /Z $fname |
| 183 | + |
| 184 | + fname="Res_"+nameofwave(wl_input) |
| 185 | + killwaves /Z $fname |
| 186 | + |
| 187 | + |
| 188 | + if (waveexists(C1) && coefs[1]< 6000 ) // 6000 is the temperature of the lamp in K, too large value may be unreasonable. |
| 189 | + return 1 |
| 190 | + endif |
| 191 | + |
| 192 | + |
| 193 | +end |
| 194 | + |
| 195 | +// ------------------------------------------------------------------------------- |
| 196 | +// ------------------------------------------------------------------------------- |
| 197 | + |
| 198 | +STATIC function gen_C1_mask (ramanshift, laser_nm , wl_input , norm_pnt , maskWave ) |
| 199 | + |
| 200 | + wave ramanshift // relative |
| 201 | + variable laser_nm // laser wavelength (nm) |
| 202 | + wave wl_input // normalized wl wave with C0 multiplied |
| 203 | + variable norm_pnt // normalization index, pnt |
| 204 | + wave maskWave |
| 205 | + |
| 206 | + variable nPnts = dimsize(ramanshift, 0) |
| 207 | + variable mid = nPnts/2 |
| 208 | + |
| 209 | + // cleanup from prev run |
| 210 | + killwindow /Z genC0C1 |
| 211 | + |
| 212 | + // make abs_wavenumber, for xaxis |
| 213 | + |
| 214 | + make /o /d /n=(nPnts) abs_wavenumber = ((1e7/laser_nm)-ramanshift)*100 |
| 215 | + make /o /d /n=2 coefs |
| 216 | + |
| 217 | + // defining initial coefs |
| 218 | + coefs[0] = 0.856e-18 |
| 219 | + coefs[1] = 2659 // 0.856e-18 |
| 220 | + |
| 221 | + |
| 222 | + Display /N=genC0C1 /K=1 wl_input vs abs_wavenumber |
| 223 | + |
| 224 | + // perform fitting, with mask applied |
| 225 | + FuncFit photons_per_unit_wavenum_abs coefs wl_input /X=abs_wavenumber /M=maskWave |
| 226 | + |
| 227 | + printf "\tMasked wl fit, obtained coefs : %5.6e, %5.6e",coefs[0],coefs[1] |
| 228 | + |
| 229 | + // generate the fit curve |
| 230 | + make /o /d /n=(nPnts) fit = photons_per_unit_wavenum_abs(coefs,abs_wavenumber) |
| 231 | + |
| 232 | + // generate C1 |
| 233 | + make /o /d /n=(nPnts) C1 = wl_input / fit |
| 234 | + |
| 235 | + //customize the graph |
| 236 | + appendtograph /W=genC0C1 fit vs abs_wavenumber |
| 237 | + |
| 238 | + ModifyGraph /W=genC0C1 grid=1,mirror=1,axThick=1.2,lblPosMode(bottom)=2;DelayUpdate |
| 239 | + ModifyGraph /W=genC0C1 lblMargin(bottom)=2,gridHair=1,manTick(left)={0,0.1,0,1},manMinor(left)={3,2},manTick(bottom)={0,0.02,6,2} |
| 240 | + ModifyGraph /W=genC0C1 manMinor(bottom)={3,2},gridRGB(left)=(13107,13107,13107),gridRGB(bottom)=(17476,17476,17476); |
| 241 | + Label /W=genC0C1 left "Intensity";DelayUpdate |
| 242 | + Label /W=genC0C1 bottom "Wavenumber / m\\S-1" |
| 243 | + ModifyGraph /W=genC0C1 fSize=25 |
| 244 | + ModifyGraph /W=genC0C1 rgb(fit)=(0,0,65535) |
| 245 | + ModifyGraph /W=genC0C1 lsize=2 |
| 246 | + SetAxis /W=genC0C1 left 0,* |
| 247 | + DoUpdate; |
| 248 | + |
| 249 | + // generate C1 |
| 250 | + make /o /d /n=(nPnts) C1 = wl_input / fit |
| 251 | + |
| 252 | + // remove fit wave |
| 253 | + string fname="fit_"+nameofwave(wl_input) |
| 254 | + killwaves /Z $fname |
| 255 | + |
| 256 | + fname="Res_"+nameofwave(wl_input) |
| 257 | + killwaves /Z $fname |
| 258 | + |
| 259 | + if (waveexists(C1) && coefs[1]< 6000 ) // 6000 is the temperature of the lamp in K, too large value may be unreasonable. |
| 260 | + return 2 |
| 261 | + endif |
| 262 | + |
| 263 | + |
| 264 | +end |
| 265 | + |
| 266 | + |
| 267 | +// ------------------------------------------------------------------------------- |
| 268 | +// ------------------------------------------------------------------------------- |
| 269 | +// Custom fit function |
| 270 | + |
| 271 | +Function photons_per_unit_wavenum_abs(w0,w) : FitFunc |
| 272 | + Wave w0 |
| 273 | + Variable w |
| 274 | + |
| 275 | + //CurveFitDialog/ These comments were created by the Curve Fitting dialog. Altering them will |
| 276 | + //CurveFitDialog/ make the function less convenient to work with in the Curve Fitting dialog. |
| 277 | + //CurveFitDialog/ Equation: |
| 278 | + //CurveFitDialog/ f(w) = a0*599584916*w^2/(exp(0.1438776877e-1*w/T)-1) |
| 279 | + //CurveFitDialog/ End of Equation |
| 280 | + //CurveFitDialog/ Independent Variables 1 |
| 281 | + //CurveFitDialog/ w |
| 282 | + //CurveFitDialog/ Coefficients 2 |
| 283 | + //CurveFitDialog/ w0[0] = a0 |
| 284 | + //CurveFitDialog/ w0[1] = T |
| 285 | + |
| 286 | + return w0[0]*599584916*w^2/(exp(0.1438776877e-1*w/w0[1])-1) |
| 287 | +End |
| 288 | + |
| 289 | +// ------------------------------------------------------------------------------- |
| 290 | +// ------------------------------------------------------------------------------- |
| 291 | + |
| 292 | +// for averaging 2D input wave across columns |
| 293 | +STATIC function do_average_custom(input) |
| 294 | + wave input |
| 295 | + |
| 296 | + variable nRows |
| 297 | + variable nCols |
| 298 | + variable i |
| 299 | + |
| 300 | + nRows=dimsize(input, 0) |
| 301 | + nCols=dimsize(input, 1) |
| 302 | + |
| 303 | + |
| 304 | + string name=nameofwave (input) |
| 305 | + |
| 306 | + string new_name |
| 307 | + sprintf new_name, "%s_avg",name |
| 308 | + printf "\t%s\t%g\t%g\r" new_name, nRows, nCols |
| 309 | + |
| 310 | + make /o/d /n=(nRows) $new_name |
| 311 | + wave output=$new_name |
| 312 | + |
| 313 | + make /o/d /n=(nRows) temp=0 |
| 314 | + |
| 315 | + for (i=0 ; i<nCols ; i=i+1) |
| 316 | + temp=temp+input [p][(i)] |
| 317 | + endfor |
| 318 | + |
| 319 | + output=temp / nCols |
| 320 | + |
| 321 | + killwaves /Z temp |
| 322 | + |
| 323 | +end |
| 324 | + |
| 325 | +// ------------------------------------------------------------------------------- |
| 326 | +// ------------------------------------------------------------------------------- |
| 327 | + |
| 328 | +// set points in input 1D wavto nan, for points where mask has values == 0 |
| 329 | +// returns wave reference |
| 330 | +STATIC function /WAVE set_nan_correspond_to_mask (input, mask) |
| 331 | + wave input |
| 332 | + wave mask |
| 333 | + |
| 334 | + variable nRows=dimsize (input, 0) |
| 335 | + variable i |
| 336 | + |
| 337 | + for (i=0 ; i<nRows ; i=i+1) |
| 338 | + if (mask[i]==0) |
| 339 | + input[i] = nan |
| 340 | + endif |
| 341 | + |
| 342 | + endfor |
| 343 | + return input |
| 344 | +end |
| 345 | +// ------------------------------------------------------------------------------- |
| 346 | +// ------------------------------------------------------------------------------- |
0 commit comments