00001 #include <jsoc_main.h>
00002 #include <mkl.h>
00003
00004 void warn(const char *fmt, ...)
00005 {
00006 va_list ap;
00007 va_start(ap, fmt);
00008 vfprintf(stderr, fmt, ap);
00009 va_end(ap);
00010 }
00011
00012 void die(const char *fmt, ...)
00013 {
00014 va_list ap;
00015 va_start(ap, fmt);
00016 vfprintf(stderr, fmt, ap);
00017 va_end(ap);
00018 exit(1);
00019 }
00020
00021 void ck(MKL_LONG status)
00022 {
00023 if (DftiErrorClass(status, DFTI_NO_ERROR))
00024 return;
00025 die(DftiErrorMessage(status));
00026 }
00027
00028 #define DORL(X)\
00029 for (int k=0; k<iter; ++k) {\
00030 cblas_scopy(4096*4098, E##X, 1, Esav##X, 1);\
00031 ck(DftiComputeForward(p, E##X));\
00032 vcMul(2049*4096, E##X, P, B##X);\
00033 ck(DftiComputeBackward(q, B##X));\
00034 vsDiv(2*2049*4096, O##X, B##X, R##X);\
00035 ck(DftiComputeForward(p, R##X));\
00036 vcMulByConj(2049*4096, R##X, P, C##X);\
00037 ck(DftiComputeBackward(q, C##X));\
00038 vsMul(2*2049*4096, Esav##X, C##X, E##X);\
00039 }
00040
00041 char *module_name = "stokes_dcon";
00042 ModuleArgs_t module_args[] = {
00043 {ARG_STRING, "in", "", "input query"},
00044 {ARG_STRING, "out", "", "output series"},
00045 {ARG_STRING, "psf", "", "PSF query"},
00046 {ARG_INT, "iter", "25", "number of R-L iterations"},
00047 {ARG_END}
00048 };
00049
00050 int DoIt() {
00051 const char *in = cmdparams_get_str(&cmdparams, "in", NULL);
00052 const char *out = cmdparams_get_str(&cmdparams, "out", NULL);
00053 const char *psf = cmdparams_get_str(&cmdparams, "psf", NULL);
00054 char source[100];
00055 int iter = cmdparams_get_int(&cmdparams, "iter", NULL);
00056 int status;
00057
00058 drms_series_exists(drms_env, out, &status);
00059 if (DRMS_SUCCESS != status)
00060 die("Output series %s does not exit\n", out);
00061
00062
00063 DRMS_RecordSet_t *rsin = drms_open_records(drms_env, in, &status);
00064 if (status || !rsin)
00065 die("Can't do drms_open_records(%s)\n", in);
00066 else
00067 warn("DRMS recordset %s opened\n", in);
00068 if (drms_stage_records(rsin, 1, 0) != DRMS_SUCCESS)
00069 {
00070 drms_close_records(rsin, DRMS_FREE_RECORD);
00071 die("Failure staging DRMS records (%s).\n", in);
00072 }
00073
00074 int nrecs = rsin->n;
00075 if (!nrecs)
00076 die("No records matching %s in found\n", in);
00077 else
00078 warn("%d records found\n", nrecs);
00079
00080
00081 DRMS_RecordSet_t *rpsf = drms_open_records(drms_env, psf, &status);
00082 if (status || !rpsf)
00083 die("Can't do drms_open_records(%s)\n", psf);
00084 DRMS_Segment_t *segpsf = drms_segment_lookup(rpsf->records[0], "psf");
00085 if (!segpsf)
00086 die("No psf segment found.\n");
00087 DRMS_Array_t *arrpsf = drms_segment_read(segpsf, DRMS_TYPE_DOUBLE, &status);
00088 if (status || !arrpsf)
00089 die("Can't read psf record %s\n", psf);
00090 else if (arrpsf->naxis != 2 || arrpsf->axis[0] != 4096 || arrpsf->axis[1] != 4096 || arrpsf->type != DRMS_TYPE_DOUBLE)
00091 die("PSF record %s does not contain 4096x4096 double precision array\n", psf);
00092 warn("PSF record %s read\n", psf);
00093
00094
00095 float *P = MKL_malloc(sizeof(float)*4096*4098, 64);
00096 if (!P)
00097 die("Can't allocate memory for array P\n");
00098 for (int j=0; j<4096; ++j)
00099 for (int i=0; i<4096; ++i)
00100 P[4098*j+i] = ((double *)arrpsf->data)[4096*j+i];
00101 drms_free_array(arrpsf);
00102 drms_close_records(rpsf, DRMS_FREE_RECORD);
00103
00104
00105 MKL_LONG lengths[2], strdfor[3], strdbak[3];
00106 DFTI_DESCRIPTOR *p, *q;
00107 lengths[0] = lengths[1] = 4096;
00108 strdfor[0] = 0; strdfor[1] = 4098; strdfor[2] = 1;
00109 strdbak[0] = 0; strdbak[1] = 2049; strdbak[2] = 1;
00110 ck(DftiCreateDescriptor(&p, DFTI_SINGLE, DFTI_REAL, 2, lengths));
00111 ck(DftiSetValue(p, DFTI_BACKWARD_SCALE, 1.0/(4096*4096)));
00112 ck(DftiSetValue(p, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX));
00113 ck(DftiSetValue(p, DFTI_INPUT_STRIDES, strdfor));
00114 ck(DftiSetValue(p, DFTI_OUTPUT_STRIDES, strdbak));
00115 ck(DftiCommitDescriptor(p));
00116 ck(DftiCreateDescriptor(&q, DFTI_SINGLE, DFTI_REAL, 2, lengths));
00117 ck(DftiSetValue(q, DFTI_BACKWARD_SCALE, 1.0/(4096*4096)));
00118 ck(DftiSetValue(q, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX));
00119 ck(DftiSetValue(q, DFTI_INPUT_STRIDES, strdbak));
00120 ck(DftiSetValue(q, DFTI_OUTPUT_STRIDES, strdfor));
00121 ck(DftiCommitDescriptor(q));
00122
00123
00124 ck(DftiComputeForward(p, P));
00125
00126
00127
00128
00129
00130
00131
00132
00133 float *Oipq = MKL_malloc(sizeof(float)*4096*4098, 64);
00134 float *Oimq = MKL_malloc(sizeof(float)*4096*4098, 64);
00135 float *Oipu = MKL_malloc(sizeof(float)*4096*4098, 64);
00136 float *Oimu = MKL_malloc(sizeof(float)*4096*4098, 64);
00137 float *Oipv = MKL_malloc(sizeof(float)*4096*4098, 64);
00138 float *Oimv = MKL_malloc(sizeof(float)*4096*4098, 64);
00139 float *Eipq = MKL_malloc(sizeof(float)*4096*4098, 64);
00140 float *Eimq = MKL_malloc(sizeof(float)*4096*4098, 64);
00141 float *Eipu = MKL_malloc(sizeof(float)*4096*4098, 64);
00142 float *Eimu = MKL_malloc(sizeof(float)*4096*4098, 64);
00143 float *Eipv = MKL_malloc(sizeof(float)*4096*4098, 64);
00144 float *Eimv = MKL_malloc(sizeof(float)*4096*4098, 64);
00145 float *Esavipq = MKL_malloc(sizeof(float)*4096*4098, 64);
00146 float *Esavimq = MKL_malloc(sizeof(float)*4096*4098, 64);
00147 float *Esavipu = MKL_malloc(sizeof(float)*4096*4098, 64);
00148 float *Esavimu = MKL_malloc(sizeof(float)*4096*4098, 64);
00149 float *Esavipv = MKL_malloc(sizeof(float)*4096*4098, 64);
00150 float *Esavimv = MKL_malloc(sizeof(float)*4096*4098, 64);
00151 float *Ripq = MKL_malloc(sizeof(float)*4096*4098, 64);
00152 float *Rimq = MKL_malloc(sizeof(float)*4096*4098, 64);
00153 float *Ripu = MKL_malloc(sizeof(float)*4096*4098, 64);
00154 float *Rimu = MKL_malloc(sizeof(float)*4096*4098, 64);
00155 float *Ripv = MKL_malloc(sizeof(float)*4096*4098, 64);
00156 float *Rimv = MKL_malloc(sizeof(float)*4096*4098, 64);
00157 float *Bipq = Ripq, *Cipq = Ripq;
00158 float *Bimq = Rimq, *Cimq = Rimq;
00159 float *Bipu = Ripu, *Cipu = Ripu;
00160 float *Bimu = Rimu, *Cimu = Rimu;
00161 float *Bipv = Ripv, *Cipv = Ripv;
00162 float *Bimv = Rimv, *Cimv = Rimv;
00163 if (!Rimv)
00164 die("Can't allocate memory for array O, E, Esav, or R\n");
00165
00166
00167 DRMS_RecordSet_t *rsout = drms_create_records(drms_env, nrecs, out, DRMS_PERMANENT, &status);
00168 if (status || !rsout)
00169 die("Can't create %d records in output series %s", nrecs, out);
00170
00171
00172
00173
00174 for (int n=0; n<nrecs; ++n) {
00175 warn("Processing record #%d...\n", n);
00176 DRMS_Record_t *recin = rsin->records[n];
00177 DRMS_Record_t *recout = rsout->records[n];
00178 drms_copykeys(recout, recin, 1, kDRMS_KeyClass_Explicit);
00179
00180
00181
00182
00183 for (int wl=0; wl<6; ++wl) {
00184 DRMS_Segment_t *segIin = drms_segment_lookupnum(recin, 4*wl);
00185 DRMS_Segment_t *segQin = drms_segment_lookupnum(recin, 4*wl+1);
00186 DRMS_Segment_t *segUin = drms_segment_lookupnum(recin, 4*wl+2);
00187 DRMS_Segment_t *segVin = drms_segment_lookupnum(recin, 4*wl+3);
00188
00189 DRMS_Array_t *arrI = drms_segment_read(segIin, DRMS_TYPE_FLOAT, &status);
00190 if (status || !arrI)
00191 die("Can't read I at wavelength position %d\n", wl);
00192 DRMS_Array_t *arrQ = drms_segment_read(segQin, DRMS_TYPE_FLOAT, &status);
00193 if (status || !arrQ)
00194 die("Can't read Q at wavelength position %d\n", wl);
00195 DRMS_Array_t *arrU = drms_segment_read(segUin, DRMS_TYPE_FLOAT, &status);
00196 if (status || !arrU)
00197 die("Can't read U at wavelength position %d\n", wl);
00198 DRMS_Array_t *arrV = drms_segment_read(segVin, DRMS_TYPE_FLOAT, &status);
00199 if (status || !arrV)
00200 die("Can't read V at wavelength position %d\n", wl);
00201
00202 #pragma omp parallel for
00203
00204 for (int j=0; j<4096; ++j) {
00205 int idx = 4096*j;
00206 int id2 = 4098*j;
00207 for (int i=0; i<4096; ++i,++idx,++id2) {
00208 float tmpi = ((float *)arrI->data)[idx];
00209 float tmpq = ((float *)arrQ->data)[idx];
00210 float tmpu = ((float *)arrU->data)[idx];
00211 float tmpv = ((float *)arrV->data)[idx];
00212 Eipq[id2] = Oipq[id2] = isnanf(tmpi+tmpq) ? 0 : tmpi+tmpq;
00213 Eimq[id2] = Oimq[id2] = isnanf(tmpi-tmpq) ? 0 : tmpi-tmpq;
00214 Eipu[id2] = Oipu[id2] = isnanf(tmpi+tmpu) ? 0 : tmpi+tmpu;
00215 Eimu[id2] = Oimu[id2] = isnanf(tmpi-tmpu) ? 0 : tmpi-tmpu;
00216 Eipv[id2] = Oipv[id2] = isnanf(tmpi+tmpv) ? 0 : tmpi+tmpv;
00217 Eimv[id2] = Oimv[id2] = isnanf(tmpi-tmpv) ? 0 : tmpi-tmpv;
00218 }
00219 }
00220
00221
00222 DORL(ipq);
00223 DORL(imq);
00224 DORL(ipu);
00225 DORL(imu);
00226 DORL(ipv);
00227 DORL(imv);
00228
00229 #pragma omp parallel for
00230
00231 for (int j=0; j<4096; ++j) {
00232 int idx = 4096*j;
00233 int id2 = 4098*j;
00234 for (int i=0; i<4096; ++i,++idx,++id2) {
00235 ((float *)arrI->data)[idx] = (Eipq[id2]+Eimq[id2]+Eipu[id2]+Eimu[id2]+Eipv[id2]+Eimv[id2]) / 6.0;
00236 ((float *)arrQ->data)[idx] = 0.5 * (Eipq[id2] - Eimq[id2]);
00237 ((float *)arrU->data)[idx] = 0.5 * (Eipu[id2] - Eimu[id2]);
00238 ((float *)arrV->data)[idx] = 0.5 * (Eipv[id2] - Eimv[id2]);
00239 }
00240 }
00241
00242
00243 DRMS_Segment_t *segIout = drms_segment_lookupnum(recout, 4*wl);
00244 if (DRMS_SUCCESS != drms_segment_write(segIout, arrI, 0))
00245 die("Can't write I%d segment.\n", wl);
00246 drms_free_array(arrI);
00247
00248 DRMS_Segment_t *segQout = drms_segment_lookupnum(recout, 4*wl+1);
00249 if (DRMS_SUCCESS != drms_segment_write(segQout, arrQ, 0))
00250 die("Can't write Q%d segment.\n", wl);
00251 drms_free_array(arrQ);
00252
00253 DRMS_Segment_t *segUout = drms_segment_lookupnum(recout, 4*wl+2);
00254 if (DRMS_SUCCESS != drms_segment_write(segUout, arrU, 0))
00255 die("Can't write U%d segment.\n", wl);
00256 drms_free_array(arrU);
00257
00258 DRMS_Segment_t *segVout = drms_segment_lookupnum(recout, 4*wl+3);
00259 if (DRMS_SUCCESS != drms_segment_write(segVout, arrV, 0))
00260 die("Can't write V%d segment.\n", wl);
00261 drms_free_array(arrV);
00262
00263 drms_setkey_double(recout, "DATE", CURRENT_SYSTEM_TIME);
00264
00265
00266
00267
00268 }
00269 }
00270
00271 drms_close_records(rsin, DRMS_FREE_RECORD);
00272 drms_close_records(rsout, DRMS_INSERT_RECORD);
00273
00274 return 0;
00275 }