00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035 #include <string.h>
00036
00037 #include "naco_recipe.h"
00038 #include "irplib_strehl.h"
00039
00040
00041
00042
00043
00044 #define STREHL_MINIMUM_FLUX 100000
00045 #define STREHL_MAXIMUM_PEAK 4000
00046 #define STREHL_DEF_LOCATE_SX 512
00047 #define STREHL_DEF_LOCATE_SY 512
00048
00049 #define RECIPE_STRING "naco_img_strehl"
00050
00051
00052
00053
00054
00055 static cpl_image * naco_img_strehl_reduce(const cpl_parameterlist *,
00056 const irplib_framelist *);
00057
00058 static cpl_error_code naco_img_strehl_qc(cpl_propertylist *,
00059 cpl_propertylist *,
00060 const irplib_framelist *);
00061
00062 static cpl_error_code naco_img_strehl_save(cpl_frameset *,
00063 const cpl_parameterlist *,
00064 const cpl_propertylist *,
00065 const cpl_propertylist *,
00066 const cpl_image *,
00067 const irplib_framelist *,
00068 int);
00069
00070 NACO_RECIPE_DEFINE(naco_img_strehl,
00071 NACO_PARAM_STAR_R |
00072 NACO_PARAM_BG_RINT |
00073 NACO_PARAM_BG_REXT,
00074 "Strehl computation recipe",
00075 RECIPE_STRING " -- NACO Strehl Ratio recipe.\n"
00076 "This recipe estimates the strehl ratio and its error "
00077 "bound.\nThe Set Of Frames (sof-file) must specify at "
00078 "least one pair of files and they must be tagged either\n"
00079 "NACO-raw-file.fits " NACO_IMG_STREHL_CAL " or\n"
00080 "NACO-raw-file.fits " NACO_IMG_STREHL_TECH "\n");
00081
00082
00083
00084
00085
00086 static struct {
00087
00088 int mode;
00089
00090 double pscale;
00091 const char * filter;
00092 double pos_x;
00093 double pos_y;
00094 double strehl;
00095 double strehl_err;
00096 double star_bg;
00097 double star_peak;
00098 double star_flux;
00099 double psf_peak;
00100 double psf_flux;
00101 double bg_noise;
00102 } naco_img_strehl_config;
00103
00104
00108
00109
00110
00111
00112
00113
00114
00115
00122
00123 static int naco_img_strehl(cpl_frameset * framelist,
00124 const cpl_parameterlist * parlist)
00125 {
00126 cpl_errorstate cleanstate = cpl_errorstate_get();
00127 irplib_framelist * allframes = NULL;
00128 irplib_framelist * rawframes = NULL;
00129 irplib_framelist * framepair = NULL;
00130 cpl_frame * frame1 = NULL;
00131 cpl_frame * frame2 = NULL;
00132 cpl_image * img = NULL;
00133 cpl_propertylist * qclist = cpl_propertylist_new();
00134 cpl_propertylist * paflist = cpl_propertylist_new();
00135 int nframes, npairs;
00136 int nb_good = 0;
00137 int i;
00138
00139
00140 irplib_check(naco_dfs_set_groups(framelist),
00141 "Could not group the input frames");
00142
00143 allframes = irplib_framelist_cast(framelist);
00144 skip_if(allframes == NULL);
00145 irplib_check(rawframes
00146 = irplib_framelist_extract_regexp(allframes,
00147 "^(" NACO_IMG_STREHL_CAL
00148 "|" NACO_IMG_STREHL_TECH
00149 ")$", CPL_FALSE),
00150 "Could not load the raw frames");
00151 irplib_framelist_empty(allframes);
00152
00153 naco_img_strehl_config.mode = 0;
00154 if (cpl_frameset_find(framelist, NACO_IMG_STREHL_CAL))
00155 naco_img_strehl_config.mode = 1;
00156
00157 if (cpl_frameset_find(framelist, NACO_IMG_STREHL_TECH)) {
00158 irplib_ensure(!naco_img_strehl_config.mode, CPL_ERROR_INCOMPATIBLE_INPUT,
00159 "Mixing of DO categories " NACO_IMG_STREHL_CAL " and "
00160 NACO_IMG_STREHL_TECH "is not supported");
00161 naco_img_strehl_config.mode = 2;
00162 }
00163
00164
00165 nframes = irplib_framelist_get_size(rawframes);
00166 skip_if_lt(nframes, 2, "frames");
00167
00168 if (nframes % 2) {
00169 cpl_msg_warning(cpl_func, "The SOF comprises an odd number (%d) of raw "
00170 "frames, ignoring the last", nframes);
00171 skip_if(irplib_framelist_erase(rawframes, nframes - 1));
00172 }
00173 npairs = nframes/2;
00174
00175 framepair = irplib_framelist_new();
00176
00177
00178 for (i=0; i < npairs; i++) {
00179 cpl_error_code error;
00180
00181
00182 cpl_msg_info(cpl_func, "Reducing pair %d out of %d", i+1, npairs);
00183
00184 frame1 = irplib_framelist_unset(rawframes, 0, NULL);
00185 error = irplib_framelist_set(framepair, frame1, 0);
00186 bug_if(error);
00187
00188 skip_if(irplib_framelist_load_propertylist(framepair, 0, 0, "^("
00189 IRPLIB_PFITS_REGEXP_RECAL "|"
00190 NACO_PFITS_REGEXP_STREHL "|"
00191 NACO_PFITS_REGEXP_STREHL_PAF
00192 ")$", CPL_FALSE));
00193
00194 frame2 = irplib_framelist_unset(rawframes, 0, NULL);
00195 error = irplib_framelist_set(framepair, frame2, 1);
00196 bug_if(error);
00197
00198 skip_if(irplib_framelist_load_propertylist_all(framepair, 0, "^("
00199 NACO_PFITS_REGEXP_STREHL
00200 ")$", CPL_FALSE));
00201
00202 img = naco_img_strehl_reduce(parlist, framepair);
00203
00204 if (img == NULL) {
00205 if (npairs > 1)
00206 irplib_error_recover(cleanstate, "Could not reduce pair number "
00207 "%d:", i+1);
00208 } else {
00209
00210 skip_if(naco_img_strehl_qc(qclist, paflist, framepair));
00211
00212
00213 bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00214 naco_img_strehl_config.mode
00215 == 1 ? NACO_IMG_STREHL_RESCAL
00216 : NACO_IMG_STREHL_RESTECH));
00217
00218 irplib_ensure(!naco_img_strehl_save(framelist, parlist, qclist,
00219 paflist, img, framepair, i+1),
00220 CPL_ERROR_FILE_IO,
00221 "Could not save the products of pair %d", i+1);
00222
00223 cpl_image_delete(img);
00224 img = NULL;
00225 cpl_propertylist_empty(qclist);
00226 cpl_propertylist_empty(paflist);
00227
00228 nb_good++;
00229 }
00230
00231
00232 irplib_framelist_empty(framepair);
00233
00234 bug_if(irplib_framelist_get_size(framepair) != 0);
00235
00236 }
00237
00238 bug_if(irplib_framelist_get_size(rawframes) != 0);
00239
00240 irplib_ensure(nb_good > 0, CPL_ERROR_DATA_NOT_FOUND,
00241 "None of the %d pairs of frames could be reduced", npairs);
00242
00243 end_skip;
00244
00245 cpl_image_delete(img);
00246 irplib_framelist_delete(allframes);
00247 irplib_framelist_delete(rawframes);
00248 irplib_framelist_delete(framepair);
00249 cpl_propertylist_delete(qclist);
00250 cpl_propertylist_delete(paflist);
00251
00252 return cpl_error_get_code();
00253 }
00254
00255
00262
00263 static cpl_image * naco_img_strehl_reduce(const cpl_parameterlist * parlist,
00264 const irplib_framelist * framepair)
00265 {
00266
00267 const cpl_frame * frame1 = irplib_framelist_get_const(framepair, 0);
00268 const cpl_frame * frame2 = irplib_framelist_get_const(framepair, 1);
00269 const cpl_propertylist * plist1
00270 = irplib_framelist_get_propertylist_const(framepair, 0);
00271 const cpl_propertylist * plist2
00272 = irplib_framelist_get_propertylist_const(framepair, 1);
00273 const char * sval1;
00274 const char * sval2;
00275 cpl_image * im1 = NULL;
00276 cpl_image * im2 = NULL;
00277
00278
00279 double psigmas[] = {5.0, 2.0, 1.0, 0.5};
00280 const int nsigmas = (int)(sizeof(psigmas)/sizeof(double));
00281 cpl_size isigma;
00282 cpl_vector * sigmas = NULL;
00283 cpl_apertures * apert = NULL;
00284 double dval;
00285 double pixscale;
00286 double lam, dlam;
00287 int iflux;
00288 int ndit;
00289
00290
00291 bug_if(cpl_error_get_code());
00292
00293 naco_img_strehl_config.pscale = -1.0;
00294 naco_img_strehl_config.pos_x = -1.0;
00295 naco_img_strehl_config.pos_y = -1.0;
00296 naco_img_strehl_config.strehl = -1.0;
00297 naco_img_strehl_config.strehl_err = -1.0;
00298 naco_img_strehl_config.star_bg = -1.0;
00299 naco_img_strehl_config.star_peak = -1.0;
00300 naco_img_strehl_config.star_flux = -1.0;
00301 naco_img_strehl_config.psf_peak = -1.0;
00302 naco_img_strehl_config.psf_flux = -1.0;
00303 naco_img_strehl_config.bg_noise = -1.0;
00304
00305
00306 irplib_check(sval1 = naco_pfits_get_filter(plist1);
00307 sval2 = naco_pfits_get_filter(plist2);
00308 pixscale = naco_pfits_get_pixscale(plist1);
00309 dval = naco_pfits_get_pixscale(plist2),
00310 "Could not load the filter names and Pixel-scales");
00311
00312 irplib_ensure(!strcmp(sval1, sval2), CPL_ERROR_INCOMPATIBLE_INPUT,
00313 "The filters in the pair are different: %s <=> %s", sval1, sval2);
00314
00315 irplib_ensure(fabs(pixscale-dval) <= 1e-3, CPL_ERROR_INCOMPATIBLE_INPUT,
00316 "The pixel-scales in the pair are different: %g <=> %g",
00317 pixscale, dval);
00318
00319 naco_img_strehl_config.pscale = pixscale;
00320 naco_img_strehl_config.filter = sval1;
00321
00322 cpl_msg_info(cpl_func, "Filter: [%s]", naco_img_strehl_config.filter);
00323 cpl_msg_info(cpl_func, "Pixel scale: [%g]", naco_img_strehl_config.pscale);
00324
00325
00326 cpl_msg_info(cpl_func, "---> Loading the pair of input images");
00327 im1 = cpl_image_load(cpl_frame_get_filename(frame1), CPL_TYPE_FLOAT, 0, 0);
00328 skip_if(0);
00329 im2 = cpl_image_load(cpl_frame_get_filename(frame2), CPL_TYPE_FLOAT, 0, 0);
00330 skip_if(0);
00331
00332
00333 cpl_msg_info(cpl_func, "---> Subtracting input images");
00334 skip_if(cpl_image_subtract(im1, im2));
00335 cpl_image_delete(im2);
00336 im2 = NULL;
00337
00338
00339 irplib_check(naco_get_filter_infos(naco_img_strehl_config.filter, &lam, &dlam),
00340 "Cannot get filter infos [%s]", naco_img_strehl_config.filter);
00341
00342 cpl_msg_warning(cpl_func, "LAM=%g, DLAM=%g", lam, dlam);
00343
00344 cpl_msg_info(cpl_func, "---> Detecting a bright star using %d sigma-levels "
00345 "ranging from %g down to %g", nsigmas, psigmas[0],
00346 psigmas[nsigmas-1]);
00347 sigmas = cpl_vector_wrap(nsigmas, psigmas);
00348 irplib_check(apert = cpl_apertures_extract_window(im1, sigmas,
00349 (int)(cpl_image_get_size_x(im1)-STREHL_DEF_LOCATE_SX)/2,
00350 (int)(cpl_image_get_size_y(im1)-STREHL_DEF_LOCATE_SY)/2,
00351 (int)(cpl_image_get_size_x(im1)+STREHL_DEF_LOCATE_SX)/2,
00352 (int)(cpl_image_get_size_y(im1)+STREHL_DEF_LOCATE_SY)/2,
00353 &isigma),
00354 "Could not detect the star");
00355
00356 skip_if(irplib_apertures_find_max_flux(apert, &iflux, 1));
00357
00358 naco_img_strehl_config.pos_x = cpl_apertures_get_centroid_x(apert, iflux);
00359 naco_img_strehl_config.pos_y = cpl_apertures_get_centroid_y(apert, iflux);
00360 cpl_apertures_delete(apert);
00361 apert = NULL;
00362 cpl_msg_info(cpl_func, "Star detected at sigma=%g, at position %g %g",
00363 psigmas[isigma],
00364 naco_img_strehl_config.pos_x,
00365 naco_img_strehl_config.pos_y);
00366 skip_if(0);
00367
00368
00369 irplib_check(naco_get_filter_infos(naco_img_strehl_config.filter, &lam, &dlam),
00370 "Cannot get filter infos [%s]", naco_img_strehl_config.filter);
00371
00372
00373 cpl_msg_info(cpl_func, "---> Computing the strehl ratio");
00374 irplib_check(irplib_strehl_compute(im1,
00375 IRPLIB_STREHL_M1, IRPLIB_STREHL_M2, lam, dlam,
00376 naco_img_strehl_config.pscale,
00377 IRPLIB_STREHL_BOX_SIZE,
00378 naco_img_strehl_config.pos_x,
00379 naco_img_strehl_config.pos_y,
00380 naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_STAR_R),
00381 naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_BG_RINT),
00382 naco_parameterlist_get_double(parlist, RECIPE_STRING, NACO_PARAM_BG_REXT),
00383 -1, -1,
00384 &(naco_img_strehl_config.strehl),
00385 &(naco_img_strehl_config.strehl_err),
00386 &(naco_img_strehl_config.star_bg),
00387 &(naco_img_strehl_config.star_peak),
00388 &(naco_img_strehl_config.star_flux),
00389 &(naco_img_strehl_config.psf_peak),
00390 &(naco_img_strehl_config.psf_flux),
00391 &(naco_img_strehl_config.bg_noise)),
00392 "Could not compute the Strehl ratio");
00393
00394
00395 ndit = naco_pfits_get_ndit(plist1);
00396 skip_if(cpl_error_get_code());
00397
00398 cpl_msg_info(cpl_func, "Strehl: %g", naco_img_strehl_config.strehl);
00399 cpl_msg_info(cpl_func, "Strehl error: %g", naco_img_strehl_config.strehl_err);
00400 cpl_msg_info(cpl_func, "Star bg: %g", naco_img_strehl_config.star_bg);
00401 cpl_msg_info(cpl_func, "Star peak: %g", naco_img_strehl_config.star_peak);
00402 cpl_msg_info(cpl_func, "Star flux: %g", naco_img_strehl_config.star_flux);
00403 cpl_msg_info(cpl_func, "PSF peak: %g", naco_img_strehl_config.psf_peak);
00404 cpl_msg_info(cpl_func, "PSF flux: %g", naco_img_strehl_config.psf_flux);
00405 cpl_msg_info(cpl_func, "Bg noise: %g", naco_img_strehl_config.bg_noise);
00406
00407 if (ndit*naco_img_strehl_config.star_flux < STREHL_MINIMUM_FLUX)
00408 cpl_msg_warning(cpl_func, "The Strehl may be unreliable, due to a too "
00409 "low star flux: %g < %g/%d",
00410 naco_img_strehl_config.star_flux,
00411 (double)STREHL_MINIMUM_FLUX, ndit);
00412
00413 if (naco_img_strehl_config.star_peak > STREHL_MAXIMUM_PEAK)
00414 cpl_msg_warning(cpl_func, "The Strehl may be unreliable, due to a too "
00415 "high star peak: %g > %g",
00416 naco_img_strehl_config.star_peak,
00417 (double)STREHL_MAXIMUM_PEAK);
00418
00419 end_skip;
00420
00421 cpl_image_delete(im2);
00422 cpl_apertures_delete(apert);
00423 cpl_vector_unwrap(sigmas);
00424
00425 if (cpl_error_get_code()) {
00426 cpl_image_delete(im1);
00427 im1 = NULL;
00428 }
00429
00430 return im1;
00431 }
00432
00433
00434
00442
00443 static cpl_error_code naco_img_strehl_qc(cpl_propertylist * qclist,
00444 cpl_propertylist * paflist,
00445 const irplib_framelist * framepair)
00446 {
00447
00448 cpl_errorstate cleanstate = cpl_errorstate_get();
00449 const cpl_propertylist * plist1
00450 = irplib_framelist_get_propertylist_const(framepair, 0);
00451 const cpl_propertylist * plist2
00452 = irplib_framelist_get_propertylist_const(framepair, 1);
00453 const char * optiname;
00454 double dval1, dval2;
00455 double mean;
00456 const double almost_zero = 1e-3;
00457
00458
00459
00460 bug_if (0);
00461
00462
00463 skip_if (cpl_propertylist_copy_property_regexp(paflist, plist1, "^("
00464 NACO_PFITS_REGEXP_STREHL_PAF
00465 ")$", 0));
00466
00467
00468 dval1 = naco_pfits_get_l0mean(plist1);
00469 dval2 = naco_pfits_get_l0mean(plist2);
00470 mean = 0.0;
00471 if (cpl_error_get_code())
00472 naco_error_reset("Could not get FITS key:");
00473 else {
00474 if (fabs(dval1) <= almost_zero) mean = dval2;
00475 else if (fabs(dval2) <= almost_zero) mean = dval1;
00476 else mean = (dval1+dval2)/2.0;
00477 }
00478 skip_if(cpl_propertylist_append_double(paflist,
00479 "ESO AOS RTC DET DST L0MEAN", mean));
00480
00481
00482 dval1 = naco_pfits_get_t0mean(plist1);
00483 dval2 = naco_pfits_get_t0mean(plist2);
00484 mean = 0.0;
00485 if (cpl_error_get_code())
00486 naco_error_reset("Could not get FITS key:");
00487 else {
00488 if (fabs(dval1) <= almost_zero) mean = dval2;
00489 else if (fabs(dval2) <= almost_zero) mean = dval1;
00490 else mean = (dval1+dval2)/2.0;
00491 }
00492 skip_if(cpl_propertylist_append_double(paflist, "ESO AOS RTC DET DST T0MEAN",
00493 mean));
00494
00495
00496 dval1 = naco_pfits_get_r0mean(plist1);
00497 dval2 = naco_pfits_get_r0mean(plist2);
00498 mean = 0.0;
00499 if (cpl_error_get_code())
00500 naco_error_reset("Could not get FITS key:");
00501 else {
00502 if (fabs(dval1) <= almost_zero) mean = dval2;
00503 else if (fabs(dval2) <= almost_zero) mean = dval1;
00504 else mean = (dval1+dval2)/2.0;
00505 }
00506 skip_if(cpl_propertylist_append_double(paflist, "ESO AOS RTC DET DST R0MEAN",
00507 mean));
00508
00509
00510 dval1 = naco_pfits_get_ecmean(plist1);
00511 dval2 = naco_pfits_get_ecmean(plist2);
00512 mean = 0.0;
00513 if (cpl_error_get_code())
00514 naco_error_reset("Could not get FITS key:");
00515 else {
00516 if (fabs(dval1) <= almost_zero) mean = dval2;
00517 else if (fabs(dval2) <= almost_zero) mean = dval1;
00518 else mean = (dval1+dval2)/2.0;
00519 }
00520 skip_if(cpl_propertylist_append_double(paflist, "ESO AOS RTC DET DST ECMEAN",
00521 mean));
00522
00523
00524 dval1 = naco_pfits_get_fluxmean(plist1);
00525 dval2 = naco_pfits_get_fluxmean(plist2);
00526 mean = 0.0;
00527 if (cpl_error_get_code())
00528 naco_error_reset("Could not get FITS key:");
00529 else {
00530 if (fabs(dval1) <= almost_zero) mean = dval2;
00531 else if (fabs(dval2) <= almost_zero) mean = dval1;
00532 else mean = (dval1+dval2)/2.0;
00533 }
00534 skip_if(cpl_propertylist_append_double(paflist,"ESO AOS RTC DET DST FLUXMEAN",
00535 mean));
00536
00537
00538 skip_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS",
00539 naco_img_strehl_config.filter));
00540
00541 optiname = naco_pfits_get_opti3_name(plist1);
00542 if (cpl_error_get_code())
00543 naco_error_reset("Could not get FITS key:");
00544 else
00545 skip_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER NDENS",
00546 optiname));
00547 optiname = naco_pfits_get_opti4_name(plist1);
00548 if (cpl_error_get_code())
00549 naco_error_reset("Could not get FITS key:");
00550 else
00551 skip_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER POL",
00552 optiname));
00553
00554
00555 mean = 0.5*(naco_pfits_get_airmass_start(plist1) +
00556 naco_pfits_get_airmass_end(plist2));
00557 if (cpl_error_get_code()) {
00558 mean = 0.0;
00559 naco_error_reset("Could not get FITS key:");
00560 }
00561 skip_if(cpl_propertylist_append_double(qclist, "ESO QC AIRMASS", mean));
00562
00563
00564 cpl_propertylist_append_double(qclist, "ESO QC STREHL",
00565 naco_img_strehl_config.strehl);
00566 cpl_propertylist_append_double(qclist, "ESO QC STREHL FLUX",
00567 naco_img_strehl_config.star_flux);
00568 cpl_propertylist_append_double(qclist, "ESO QC STREHL PEAK",
00569 naco_img_strehl_config.star_peak);
00570 cpl_propertylist_append_double(qclist, "ESO QC STREHL ERROR",
00571 naco_img_strehl_config.strehl_err);
00572 cpl_propertylist_append_double(qclist, "ESO QC STREHL RMS",
00573 naco_img_strehl_config.bg_noise);
00574 cpl_propertylist_append_double(qclist, "ESO QC STREHL POSX",
00575 naco_img_strehl_config.pos_x);
00576 cpl_propertylist_append_double(qclist, "ESO QC STREHL POSY",
00577 naco_img_strehl_config.pos_y);
00578
00579 bug_if(0);
00580
00581 bug_if (cpl_propertylist_append(paflist, qclist));
00582
00583 bug_if (cpl_propertylist_copy_property_regexp(qclist, plist1, "^("
00584 IRPLIB_PFITS_REGEXP_RECAL
00585 ")$", 0));
00586
00587 bug_if (irplib_pfits_set_airmass(qclist, framepair));
00588
00589 end_skip;
00590
00591 return cpl_error_get_code();
00592 }
00593
00594
00606
00607 static cpl_error_code naco_img_strehl_save(cpl_frameset * set_tot,
00608 const cpl_parameterlist * parlist,
00609 const cpl_propertylist * qclist,
00610 const cpl_propertylist * paflist,
00611 const cpl_image * ima,
00612 const irplib_framelist * framepair,
00613 int pair_id)
00614 {
00615 cpl_frameset * rawframes = irplib_frameset_cast(framepair);
00616 char * filename = NULL;
00617
00618
00619 bug_if(0);
00620
00621
00622 filename = cpl_sprintf(RECIPE_STRING "%02d" CPL_DFS_FITS, pair_id);
00623 skip_if (irplib_dfs_save_image(set_tot, parlist, rawframes, ima,
00624 CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00625 naco_img_strehl_config.mode == 1
00626 ? NACO_IMG_STREHL_RESCAL
00627 : NACO_IMG_STREHL_RESTECH, qclist, NULL,
00628 naco_pipe_id, filename));
00629
00630
00631 cpl_free(filename);
00632 filename = cpl_sprintf(RECIPE_STRING "%02d" CPL_DFS_PAF, pair_id);
00633 skip_if (cpl_dfs_save_paf("NACO", RECIPE_STRING, paflist, filename));
00634
00635 end_skip;
00636
00637 cpl_free(filename);
00638 cpl_frameset_delete(rawframes);
00639
00640 return cpl_error_get_code();
00641 }