void batchCubesCallback(char **pptrOutput) { int result; char *ptrOutput = *pptrOutput; NumberLength = toProcess.nbrLimbs; result = fcubes(&toProcess); // Show the number to be decomposed into sum of cubes. strcpy(ptrOutput, "<p>"); ptrOutput += strlen(ptrOutput); if (hexadecimal) { BigInteger2Hex(&toProcess, ptrOutput, groupLen); } else { BigInteger2Dec(&toProcess, ptrOutput, groupLen); } ptrOutput += strlen(ptrOutput); switch (result) { case -1: strcpy(ptrOutput, (lang==0?": This applet does not work if the number is congruent to 4 or 5 (mod 9)</p>": ": El applet no funciona si el número es congruente a 4 o 5 (mod 9)</p>")); *pptrOutput = ptrOutput + strlen(ptrOutput); return; case 1: strcpy(ptrOutput, (lang==0?": Internal error! Please send the number to the author of the applet.</p>": ": ¡Error interno!Por favor envíe este número al autor del applet.</p>")); *pptrOutput = ptrOutput + strlen(ptrOutput); return; case 2: strcpy(ptrOutput, (lang==0?": User stopped the calculation</p>":": El usuario detuvo el cálculo</p>")); *pptrOutput = ptrOutput + strlen(ptrOutput); return; } // Show decomposition in sum of 1, 2, 3 or 4 cubes. strcpy(ptrOutput, " = "); ptrOutput += strlen(ptrOutput); if (Base1.sign == SIGN_NEGATIVE) { *ptrOutput++ = '('; } if (hexadecimal) { BigInteger2Hex(&Base1, ptrOutput, groupLength); } else { BigInteger2Dec(&Base1, ptrOutput, groupLength); } ptrOutput += strlen(ptrOutput); if (Base1.sign == SIGN_NEGATIVE) { *ptrOutput++ = ')'; } strcpy(ptrOutput, cube); ptrOutput += strlen(ptrOutput); if (Base2.nbrLimbs != 1 || Base2.limbs[0].x != 0) { strcpy(ptrOutput, " + "); ptrOutput += strlen(ptrOutput); if (Base2.sign == SIGN_NEGATIVE) { *ptrOutput++ = '('; } if (hexadecimal) { BigInteger2Hex(&Base2, ptrOutput, groupLength); } else { BigInteger2Dec(&Base2, ptrOutput, groupLength); } ptrOutput += strlen(ptrOutput); if (Base2.sign == SIGN_NEGATIVE) { *ptrOutput++ = ')'; } strcpy(ptrOutput, cube); ptrOutput += strlen(ptrOutput); } if (Base3.nbrLimbs != 1 || Base3.limbs[0].x != 0) { strcpy(ptrOutput, " + "); ptrOutput += strlen(ptrOutput); if (Base3.sign == SIGN_NEGATIVE) { *ptrOutput++ = '('; } if (hexadecimal) { BigInteger2Hex(&Base3, ptrOutput, groupLength); } else { BigInteger2Dec(&Base3, ptrOutput, groupLength); } ptrOutput += strlen(ptrOutput); if (Base3.sign == SIGN_NEGATIVE) { *ptrOutput++ = ')'; } strcpy(ptrOutput, cube); ptrOutput += strlen(ptrOutput); } if (Base4.nbrLimbs != 1 || Base4.limbs[0].x != 0) { strcpy(ptrOutput, " + "); ptrOutput += strlen(ptrOutput); if (Base4.sign == SIGN_NEGATIVE) { *ptrOutput++ = '('; } if (hexadecimal) { BigInteger2Hex(&Base4, ptrOutput, groupLength); } else { BigInteger2Dec(&Base4, ptrOutput, groupLength); } ptrOutput += strlen(ptrOutput); if (Base4.sign == SIGN_NEGATIVE) { *ptrOutput++ = ')'; } strcpy(ptrOutput, cube); ptrOutput += strlen(ptrOutput); } *pptrOutput = ptrOutput; }
int phypp_main(int argc, char* argv[]) { if (argc < 2) { print("usage: make_shifts <ob_filter> [options]"); return 0; } vec1u exclude; std::string helper; read_args(argc-1, argv+1, arg_list(exclude, helper)); if (helper.empty()) { error("please provide the name of (one of) the helper target you used to " "calibrate the shifts (helper=...)"); return 1; } helper = tolower(helper); std::string scis = argv[1]; vec1d cent_ra, cent_dec; file::read_table("centroid_helper.txt", 0, cent_ra, cent_dec); vec1u ids = uindgen(cent_ra.size())+1; vec1u idex = where(is_any_of(ids, exclude)); inplace_remove(ids, idex); inplace_remove(cent_ra, idex); inplace_remove(cent_dec, idex); std::ofstream cmb("combine.sof"); vec1d shx, shy; vec1d x0, y0; bool first_line = true; uint_t nexp = 0; for (uint_t i : range(ids)) { std::string dir = scis+align_right(strn(ids[i]), 2, '0')+"/"; print(dir); vec1s files = dir+file::list_files(dir+"sci_reconstructed*-sci.fits"); inplace_sort(files); // Find out which exposures contain the helper target from which the // shifts were calibrated vec1u ignore; for (uint_t k : range(files)) { std::string f = files[k]; fits::generic_file fcubes(f); vec1s arms(24); bool badfile = false; for (uint_t u : range(24)) { if (!fcubes.read_keyword("ESO OCS ARM"+strn(u+1)+" NAME", arms[u])) { note("ignoring invalid file '", f, "'"); note("missing keyword 'ESO OCS ARM"+strn(u+1)+" NAME'"); ignore.push_back(k); badfile = true; break; } } if (badfile) continue; arms = tolower(trim(arms)); vec1u ida = where(arms == helper); if (ida.empty()) { ignore.push_back(k); } else if (x0.empty()) { // Get astrometry of IFUs from first exposure // NB: assumes the rotation is the same for all exposures, // which is anyway what kmos_combine does later on. fcubes.reach_hdu(ida[0]+1); fits::wcs astro(fcubes.read_header()); fits::ad2xy(astro, cent_ra, cent_dec, x0, y0); } } inplace_remove(files, ignore); if (files.empty()) { warning("folder ", dir, " does not contain any usable file"); continue; } for (std::string f : files) { cmb << f << " COMMAND_LINE\n"; ++nexp; } double dox = x0[0] - x0[i], doy = y0[0] - y0[i]; if (first_line) { // Ommit first line which has, by definition, no offset first_line = false; } else { shx.push_back(dox); shy.push_back(doy); } if (file::exists(dir+"helpers/shifts.txt")) { vec1d tx, ty; file::read_table(dir+"helpers/shifts.txt", 0, tx, ty); for (uint_t j : range(tx)) { shx.push_back(dox+tx[j]); shy.push_back(doy+ty[j]); } } } note("found ", nexp, " exposures"); cmb.close(); auto truncate_decimals = vectorize_lambda([](double v, uint_t nd) { return long(v*e10(nd))/e10(nd); }); shx = truncate_decimals(shx, 2); shy = truncate_decimals(shy, 2); file::write_table("shifts.txt", 10, shx, shy); return 0; }