Example AO telemetry data:
aol0_modeval_ol_15:40:18.088427319.fits
aol0_modeval_ol_15:40:34.115929146.fits
aol0_modeval_ol_15:40:57.955397265.fits
Each file contains 30000 consecutive wavefront measurements acquired a 2 kHz (15 sec total duration per file). The number of modes is 1161: this is the number of values measured at each time step.
The files are 3D images, with the last axis encoding the time step. Each slice is a 2D image of size 1161 x 1. So, the total 3D image size is 1161 x 1 x 30000.
The data matrix is assembled by pasting consecutive measurement vectors together. See pseudo code below
Input : measurement 3D cube T
Output : data matrix D
Tsize0 = 1161; // number of modes measured
Tsize2 = 30000; // number of time steps in input 3D cube
filterN = 10; // number of time steps in predictive filter
jjmax = Tsize2 - (filterN-1); // number of time steps in output data matrix D
for(jj=0; jj<jjmax; jj++)
{
for(n=0; n<filterN; n++)
{
for(i=0; i<Tsize0; i++)
{
ii = n*Tsize0 + i;
D[ii, jj] = T[i, 1, jj+n];
}
}
}
Following script used for testing:
cacao << EOF
loadfits "aol0_modeval_ol_15:40:18.088427319.fits[1:30,*,1:4000]" im00
im3Dto2D im00
imrepshiftx im00 5 mat
imswapaxis2D mat matA
savefits matA "!mat_ssmall.fits"
cudacomppsinv matA matAinv 0.01 100 VTmat
savefits matAinv "!mat_ssmall_psinv.fits"
listim
exitCLI
EOF
Input matrix (size = 150 x 3995) : mat_ssmall.fits
Output pseudoinverse (size = 150 x 3995) : mat_ssmall_psinv.fits
List of eigenvalues : eigenv.dat
Code source: See function int CUDACOMP_magma_compute_SVDpseudoInverse() in file cudacomp.c