More precise sensor readout measurement

Horshack

Forum Pro
Messages
11,231
Solutions
28
Reaction score
12,594
Location
US
In 2018 a1ex at Magic Lantern took Jim's original Z7 sensor readout method (before Jim switched to using an analog oscilloscope) and applied it to measure various Canon bodies. For higher precision and easier reproducibility, a1ex cycled an LED on an Arduino board, whose frequency can be carefully controlled. He chose 500 Hz (1000 toggles/second). This frequency is convenient because it creates a simple 1ms per-band relationship. He photographs the LED with the camera being tested, then runs the resulting photo through a Matlab script he wrote that automatically calculates the number of bands captured on the image, from which the readout rate can be calculated.

I've applied a1ex method to retest some other bodies. I'm not able to fill the entire image with the small LED on my Arduino so I instead calculate the number of bands manually from a single band I can fit onto the image, then divide that by the image height to extrapolate the full-image band count. This manual method has the benefit of accurately handling partial-band remainders, which is important for very fast stacked sensors.

Here is the method applied on the Nikon Z9. I use a fast shutter speed (1/2000) to get clear delineation from the bands.


Nikon Z9 full sensor readout using an Arduino LED flashing at 500 Hz

Note that I measure a full band (dark+light), which is necessary to account for the asymmetrical illumination from an LED being power on vs off (ie, LED turns on immediately but fades when powered off - I guess; I'm no expert on LEDs :-)

Here are a few other measurements I've done so far:

Z6 JPG (ie, 12-bit raw):
Band Height = 333. 4024/333 = 12.08408408408408, * 2 = 24.16ms
1000/24.16 = 1/41.37 (shutter speed parlance)

Z6 14-bit raw:
Band Height = 171, 4024/171 = 23.53216374269006, * 2 = 47.06ms
1000/47.06 = 1/21.24 (shutter speed parlance)

Sony ZV1 raw (should apply to all of the Sony 1" stacked sensor cameras):
Band Height = 948, 3648/948 = 3.848101265822785, *2 = 7.69ms
1000/7.69 = 1/129.93 (shutter speed parlance)
 

Attachments

  • 4398996.jpg
    4398996.jpg
    460.8 KB · Views: 0
Last edited:
There is a significant measurement error in the OP caused by lens distortion corrections. Rather than correct the OP I decided to leave it up and post the corrections in subsequent posts. In this post I'll describe the error, using the Z6 as the test subject.

In the OP I measure the height of a single band and then calculate the # bands by dividing into the image height. But the height of the band I measured is actually wrong because the images have Nikon's embedded lens distortion correction applied . The projection of bands in these images is a sensor phenomena, not optical, so the application of Nikon's lens correction profile actually creates fabricated barrel distortion in my images! This causes the bands to be rendered thicker in the center than actual size.

I used a Nikon 24-70 f/4 on the Z6 and 24-120 f/4 on the Z9, both at their maximum focal lengths, both lenses with significant distortions and thus correction profiles, so the error is magnified.

Here is an animated PNG showing two measurements on the Z6 for the same raw file - one with Nikon's/Adobe's compulsory lens corrections applied (yielding wrong measurement), and another with the compulsory lens corrections circumvented by stripping the correction profile from the raw using exiftool (yielding correct measurement). The animation alternates between the two measurements every 3 seconds.

Animation: Z6 Arduino LED measurement, with and without lens corrections

Notice the fabricated barrel distortion in the lens-corrected image.

I'll post corrections for the Z9 and ZV1 later today...
 
Last edited:
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
 
Last edited:
There is a significant measurement error in the OP caused by lens distortion corrections. Rather than correct the OP I decided to leave it up and post the corrections in subsequent posts. In this post I'll describe the error, using the Z6 as the test subject.

In the OP I measure the height of a single band and then calculate the # bands by dividing into the image height. But the height of the band I measured is actually wrong because the images have Nikon's embedded lens distortion correction applied . The projection of bands in these images is a sensor phenomena, not optical, so the application of Nikon's lens correction profile actually creates fabricated barrel distortion in my images! This causes the bands to be rendered thicker in the center than actual size.

I used a Nikon 24-70 f/4 on the Z6 and 24-120 f/4 on the Z9, both at their maximum focal lengths, both lenses with significant distortions and thus correction profiles, so the error is magnified.

Here is an animated PNG showing two measurements on the Z6 for the same raw file - one with Nikon's/Adobe's compulsory lens corrections applied (yielding wrong measurement), and another with the compulsory lens corrections circumvented by stripping the correction profile from the raw using exiftool (yielding correct measurement). The animation alternates between the two measurements every 3 seconds.

Animation: Z6 Arduino LED measurement, with and without lens corrections

Notice the fabricated barrel distortion in the lens-corrected image.

I'll post corrections for the Z9 and ZV1 later today...
Try the test with no lens installed.


 
There is a significant measurement error in the OP caused by lens distortion corrections. Rather than correct the OP I decided to leave it up and post the corrections in subsequent posts. In this post I'll describe the error, using the Z6 as the test subject.

In the OP I measure the height of a single band and then calculate the # bands by dividing into the image height. But the height of the band I measured is actually wrong because the images have Nikon's embedded lens distortion correction applied . The projection of bands in these images is a sensor phenomena, not optical, so the application of Nikon's lens correction profile actually creates fabricated barrel distortion in my images! This causes the bands to be rendered thicker in the center than actual size.

I used a Nikon 24-70 f/4 on the Z6 and 24-120 f/4 on the Z9, both at their maximum focal lengths, both lenses with significant distortions and thus correction profiles, so the error is magnified.

Here is an animated PNG showing two measurements on the Z6 for the same raw file - one with Nikon's/Adobe's compulsory lens corrections applied (yielding wrong measurement), and another with the compulsory lens corrections circumvented by stripping the correction profile from the raw using exiftool (yielding correct measurement). The animation alternates between the two measurements every 3 seconds.

Animation: Z6 Arduino LED measurement, with and without lens corrections

Notice the fabricated barrel distortion in the lens-corrected image.

I'll post corrections for the Z9 and ZV1 later today...
Try the test with no lens installed.

https://blog.kasson.com/the-last-word/how-fast-is-the-gfx-100-ii-electronic-shutter/

https://blog.kasson.com/gfx-100-ii/gfx-100-ii-edr-shutter-speed-in-cl-mode/
Hi Jim, Yep, I have a 60Hz AC LED bulb I use for this. It's 60Hz / 120 cycles at 100% power and 1920Hz / 3840 cycles at < 100%. I posted a sample here.

Now that I know to look out for lens correction it's just as easy to shoot with a lens and just strip the lens correction off the image.
 
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
 
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
 
Last edited:
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
Thanks Horshack. I was skirting around the question of what was the PWM duty cycle, and we have the frequency which then helps to define the signal, if I wanted to repeat it for example. No worries if it wasn't measured or known.
 
Corrected vs OP (removed lens distortion correction).

All raw compression and jpg settings yielded the same readout speeds, so the only two results presented are FX and DX raw, the latter of which has the same read rate/row as FX, just with fewer rows.





 

Attachments

  • 4399130.jpg
    4399130.jpg
    528.8 KB · Views: 0
  • 4399129.jpg
    4399129.jpg
    800.8 KB · Views: 0
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
Thanks Horshack. I was skirting around the question of what was the PWM duty cycle, and we have the frequency which then helps to define the signal, if I wanted to repeat it for example. No worries if it wasn't measured or known.
I imagine the duty cycle might be a bit complicated to reverse-engineer since it likely factors in the unique luminance characteristics related to the on/off timing of the bulb. Way outside my area of expertise. Here's an animation I just did that at least shows the height of the on/off bands as projected by the sensor readout at 100%, 75%, 50%, and 25% brightness of the bulb. The crop is at an AC power boundary.

Animation: TP-Link KL-125 at 100%, 75%, 50%, and 25% brightness (100% crop)
 
Last edited:
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
Thanks Horshack. I was skirting around the question of what was the PWM duty cycle, and we have the frequency which then helps to define the signal, if I wanted to repeat it for example. No worries if it wasn't measured or known.
I imagine the duty cycle might be a bit complicated to reverse-engineer since it likely factors in the unique luminance characteristics related to the on/off timing of the bulb. Way outside my area of expertise. Here's an animation I just did that at least shows the height of the on/off bands as projected by the sensor readout at 100%, 75%, 50%, and 25% brightness of the bulb. The crop is at an AC power boundary.

Animation: TP-Link KL-125 at 100%, 75%, 50%, and 25% brightness (100% crop)
Ah that's cool and helpful thanks.

When your measuring your height, band I suppose some small error could exist but it looks a good an quite easy method.
 
Had to switch to a non-native lens since distortion correction can't be disabled in video. These are with a Zeiss 100MP ZE on Fringer adapter. Two benefits to switching - can fit entire LED in frame and cleaner band edges due to larger aperture / lower ISO.


8K30p H.265 10-bit internal

All video modes:
  • 8k30p 14.30ms 1/70
  • 8k24p 14.30ms 1/70
  • 4K120p 4.89ms 1/204
  • 4k60p Extended Oversampling = OFF 4.93ms 1/202
  • 4k60p Extended Oversampling = ON 14.4ms 1/69
  • 4k30p 14.4ms 1/69
  • 4k24p 14.4ms 1/69
  • 1080120p 4.90ms 1/203
  • 108060p 4.90ms 1/203
  • 108030p 4.90ms 1/203
In summary there are two sampling rates:
  • ~1/70 (8K/4K oversampled)
  • ~1/200 (4k120p, 4K60p not oversampled, all 1080), which is likely line-skipped and/or binned
I checked raw video and H.265 8-bit / H.264 8-bit - no difference.
 

Attachments

  • 4399304.jpg
    4399304.jpg
    676.6 KB · Views: 0
Last edited:
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
Thanks Horshack. I was skirting around the question of what was the PWM duty cycle, and we have the frequency which then helps to define the signal, if I wanted to repeat it for example. No worries if it wasn't measured or known.
I imagine the duty cycle might be a bit complicated to reverse-engineer since it likely factors in the unique luminance characteristics related to the on/off timing of the bulb. Way outside my area of expertise. Here's an animation I just did that at least shows the height of the on/off bands as projected by the sensor readout at 100%, 75%, 50%, and 25% brightness of the bulb. The crop is at an AC power boundary.

Animation: TP-Link KL-125 at 100%, 75%, 50%, and 25% brightness (100% crop)
Ah that's cool and helpful thanks.

When your measuring your height, band I suppose some small error could exist but it looks a good an quite easy method.
This error can be reduced by
  • measuring several bands at a time and dividing their total height by the number of bands
  • repeating the measurement several times by identifying a new set of points to measure the height
I expect it is going to be a small fraction of a percent.
 
Here's a Z6 photo of a 60 Hz AC LED light bulb with a < 100% brightness PWM of 1920 Hz, where the effect of the lens correction applied to a sensor-created projection is more obvious. To restate, the bands are entirely the creation of the rolling shutter readout on a cycling light source and are not a projection of the lens, which means applying distortion correction to the horizontal sensor bands actually creates distortion rather than correcting it.

Animation: Lens correction on sensor-projected rolling shutter bands
I don't think I would have thought about that.

This probably doesn't matter but your PWM drive.

It's 1920Hz, less than 100% brightness. Does this mean it's a duty cycle of say 0.9 (for example).

For the switch on time. Assuming it's not a phosphored benefited LED (indirect) but a direct unless it's something rather abonornal expect it to have light intensity at the level expected of the current within say 5ns or less.

It's one thing we don't measure for the interior of car LEDs. We measure lots of things, to ensure a user sat in the vehicle sees the same colours and intensity everywhere across a wide range of temps and vehicle voltages but not the ns switch on time.
Duty cycle varies based on intensity but all intensities from 1% to 99% are PWM 1920Hz. It's a TP-Link Kasa KL-125 WiFi Smartbulb , Hardware Rev 3.0.
Thanks Horshack. I was skirting around the question of what was the PWM duty cycle, and we have the frequency which then helps to define the signal, if I wanted to repeat it for example. No worries if it wasn't measured or known.
I imagine the duty cycle might be a bit complicated to reverse-engineer since it likely factors in the unique luminance characteristics related to the on/off timing of the bulb. Way outside my area of expertise. Here's an animation I just did that at least shows the height of the on/off bands as projected by the sensor readout at 100%, 75%, 50%, and 25% brightness of the bulb. The crop is at an AC power boundary.

Animation: TP-Link KL-125 at 100%, 75%, 50%, and 25% brightness (100% crop)
Ah that's cool and helpful thanks.

When your measuring your height, band I suppose some small error could exist but it looks a good an quite easy method.
This error can be reduced by
  • measuring several bands at a time and dividing their total height by the number of bands
  • repeating the measurement several times by identifying a new set of points to measure the height
I expect it is going to be a small fraction of a percent.
I was thinking if the Y axis was ploted on a graph Vs magnitude it may be another route.
 
Had to switch to a non-native lens since distortion correction can't be disabled in video. These are with a Zeiss 100MP ZE on Fringer adapter. Two benefits to switching - can fit entire LED in frame and cleaner band edges due to larger aperture / lower ISO.


8K30p H.265 10-bit internal

All video modes:
  • 8k30p 14.30ms 1/70
  • 8k24p 14.30ms 1/70
  • 4K120p 4.89ms 1/204
  • 4k60p Extended Oversampling = OFF 4.93ms 1/202
  • 4k60p Extended Oversampling = ON 14.4ms 1/69
  • 4k30p 14.4ms 1/69
  • 4k24p 14.4ms 1/69
  • 1080120p 4.90ms 1/203
  • 108060p 4.90ms 1/203
  • 108030p 4.90ms 1/203
In summary there are two sampling rates:
  • ~1/70 (8K/4K oversampled)
  • ~1/200 (4k120p, 4K60p not oversampled, all 1080), which is likely line-skipped and/or binned
I checked raw video and H.265 8-bit / H.264 8-bit - no difference.
It's a pretty quick camera.
 
Had to switch to a non-native lens since distortion correction can't be disabled in video. These are with a Zeiss 100MP ZE on Fringer adapter. Two benefits to switching - can fit entire LED in frame and cleaner band edges due to larger aperture / lower ISO.


8K30p H.265 10-bit internal

All video modes:
  • 8k30p 14.30ms 1/70
  • 8k24p 14.30ms 1/70
  • 4K120p 4.89ms 1/204
  • 4k60p Extended Oversampling = OFF 4.93ms 1/202
  • 4k60p Extended Oversampling = ON 14.4ms 1/69
  • 4k30p 14.4ms 1/69
  • 4k24p 14.4ms 1/69
  • 1080120p 4.90ms 1/203
  • 108060p 4.90ms 1/203
  • 108030p 4.90ms 1/203
In summary there are two sampling rates:
  • ~1/70 (8K/4K oversampled)
  • ~1/200 (4k120p, 4K60p not oversampled, all 1080), which is likely line-skipped and/or binned
I checked raw video and H.265 8-bit / H.264 8-bit - no difference.
It's a pretty quick camera.
That's true but Nikon is running the sensor at 1/4 it's maximum readout speed for its video modes, which means it has more rolling shutter than it needs to. I discussed this here.
 
Had to switch to a non-native lens since distortion correction can't be disabled in video. These are with a Zeiss 100MP ZE on Fringer adapter. Two benefits to switching - can fit entire LED in frame and cleaner band edges due to larger aperture / lower ISO.


8K30p H.265 10-bit internal

All video modes:
  • 8k30p 14.30ms 1/70
  • 8k24p 14.30ms 1/70
  • 4K120p 4.89ms 1/204
  • 4k60p Extended Oversampling = OFF 4.93ms 1/202
  • 4k60p Extended Oversampling = ON 14.4ms 1/69
  • 4k30p 14.4ms 1/69
  • 4k24p 14.4ms 1/69
  • 1080120p 4.90ms 1/203
  • 108060p 4.90ms 1/203
  • 108030p 4.90ms 1/203
In summary there are two sampling rates:
  • ~1/70 (8K/4K oversampled)
  • ~1/200 (4k120p, 4K60p not oversampled, all 1080), which is likely line-skipped and/or binned
I checked raw video and H.265 8-bit / H.264 8-bit - no difference.
It's a pretty quick camera.
That's true but Nikon is running the sensor at 1/4 it's maximum readout speed for its video modes, which means it has more rolling shutter than it needs to. I discussed this here.
I recall your post. I remember searching the web and found some potential reason but don't recall where I read it. Nothing concrete or I would have posted back. It was something to do with either how many rows it read at once, local ram or both. I forget.
 


Full Results
  • 14-bit NEF 50.93ms 1/19.63
  • 12-bit NEF or JPG 26.56ms 1/37.65
  • 4k30p/24p 22.04ms 1/45.37
  • 1080 120p 2.60ms 1/384.25
  • 1080 60p/30p 3.64ms 1/274.07
 
Last edited:


Full Results
  • 14-bit NEF 65.91ms 1/15.17
  • 12-bit NEF 50.96ms 1/19.62
  • 4k30p/24p 29.79ms 1/33.56
  • 1080 120p 7.012ms 1/142.59
  • 1080 60p/30p 10.64ms 1/1/93.98
 

Attachments

  • 4399371.jpg
    4399371.jpg
    383.3 KB · Views: 0


Full Results
  • 14-bit NEF 65.91ms 1/15.17
  • 12-bit NEF 50.96ms 1/19.62
  • 4k30p/24p 29.79ms 1/33.56
  • 1080 120p 7.012ms 1/142.59
  • 1080 60p/30p 10.64ms 1/1/93.98
Thanks Horshack. Have you thought that the numbers were designed to be and if they may be different? It's not an important question just something that crossed my mind after reading the outputs of your hard work.
 

Keyboard shortcuts

Back
Top