puls-lab / phoeniks

A free and open-source (FOSS) Python class to exctract the refractive index and absorption coefficient from time traces of a THz Time Domain Spectrometer (THz-TDS).
GNU General Public License v3.0
9 stars 7 forks source link

wobbling signal whiling extracting (n,k) of commom substrate #1

Closed pp21tig closed 1 year ago

pp21tig commented 1 year ago

Hi, it's a wonderful package of dealing with THz-TDS data. But I met with some problems extracting optical constant of some simple material. For instance, Al2O3. I have one sample data, and one reference data(it's actually a THz signal transmission through an empty hole). First, the data I got, (n,k) always wobbling versus frequency. Second, the value of (n,k) depends strongly on the thickness I choose. (like it should be 450-550um) I think the problem lies "run_optimization". I would suggest you using other algorithm like the paper I list below. DOI: 10.1109/2944.571775

TimVog commented 1 year ago

Hi, it's a wonderful package of dealing with THz-TDS data.

Thank you for the kind words, I'm happy if the package is useful 😃

But I met with some problems extracting optical constant of some simple material. For instance, Al2O3. I have one sample data, and one reference data(it's actually a THz signal transmission through an empty hole). First, the data I got, (n,k) always wobbling versus frequency. Second, the value of (n,k) depends strongly on the thickness I choose. (like it should be 450-550um)

This should not happen. Typically, oscillations in the refractive index are observed when the thickness is not chosen correctly. In the end, the "get_thickness_array"-method from extraction.py is using exactly this fact, trying out different thicknesses and see, at which thickness it "wiggles" the least amount. But I guess you tried already many different thicknesses between 450 µm to 550 µm?

I think the problem lies "run_optimization". I would suggest you using other algorithm like the paper I list below. DOI: 10.1109/2944.571775

There is definetly room for improvement in "run_optimization". Currently, for each frequency the n and k are optimized which minimizes the error function, which takes the difference between the model transfer function (based on Fresnel-equation and input data) and the numerical transfer function (measured sample / measured reference). There are different ways how to create a single "error" signal from this differnence, that is the reason why there are multiple error_functions defined in "error_optimization.py". I didn't figure out yet, which one is best/most suitable.

The other reason why this is currently limited: Since there are many local minima at each frequency, the refractive index tend to fluctuate strongly around (at least when I implemented it first). A breakthrough was to take the solution from the previous frequency as a starting value for the next frequency, which made the solution much more behaved (but unfortunately makes it difficult to parallelize the loop, but this is a different construction site). The Nelder-Mead algorithm, with the many local minimia, works well & fast when the start value is already close to the solution.

I don't think the oscillations come from the algorithm itself but from the transfer function, which incorporated the echos. One problem (which I can think of) which could lead to oscillating refractive index even with the "correct" thickness would be a slight wedge of the sample. The transfer function assumes a plane-parallel sample, but if your sample has a wedge, you have no single thickness anymore and the found refractive index could maybe start to oscillate? If you have a caliper, you can maybe make multiple measurements around the disk near the edge and check how much the value fluctuate?

I would suggest you using other algorithm like the paper I list below. DOI: 10.1109/2944.571775

Thanks for the paper. I was aware of it and took a brief look, but besides the more complicated mathematical description (they try to fit a paraboloid to the error function if I remember correctly), they try to suppress the influence of the echos. Later literature showed that the information in the echos is useful and can lead to more precise determination of n and k. I guess if the algoirhtm they mention in the paper is used, the solution should also be less prone to oscillations, since the echos are suppressed and the transfer function does not need to account for them?

Nevertheless, I will give the algorithms in the paper another look and try to implement them. If that is successful, the user can choose what algorithm he/she would like to use to solve the problem.

I guess from the thickness you mentioned, the echos are separate from each other and it would fall in the thick sample category, correct?

If you want, you can attach the reference file and sample file and I can also ake a look.

pp21tig commented 1 year ago

Thanks for your quick and helpful reply. It's really helpful.

oscillations in the refractive index are observed when the thickness is not chosen correctly

I agree with what you said. And I have tried using "get_thickness_array" to find an optimal thickness. And it seems to work. You can see it from the reference file Fig. 1. And then I used this thickness like 514um or 500um to extract the optical constant (n,k). But it fails. See fig. 2.

If you have a caliper, you can maybe make multiple measurements around the disk near the edge and check how much the value fluctuate?

For this point, I haven't considered it before. Thanks for the reminder. But I think it won't be the main issue. Two reasons:

I guess from the thickness you mentioned, the echos are separate from each other and it would fall in the thick sample category, correct? If you want, you can attach the reference file and sample file and I can also ake a look.

Yeah, I have attached the raw data below. Appreciate you can help me look at this. And the "vac" labeled is signal from a through hole. "Al2O3" labeled is the sample's signal. One thing to mention is that since the data was taken while sample mounted into a cryostat, there is a signal from the optical window. It's about 16ps left behind the main pulse. You can both see it from the sample and reference data. What i did it's using a window to eliminate it. After processing, the data looks like Fig.3. (figures and the program i used was in the Zip file) Al2O3_10-00K_z7-88mm_0-00T_Hum2-97_20221022_234050.pulse.csv Vac4mm_10-00K_z15-93mm_0-00T_Hum2-97_20221022_234607.pulse.csv github_phoeniks_fig.zip