public void readOrbitData() throws IOException { if (_productFile instanceof DorisOrbitProductFile) { final DorisOrbitProductFile dorisProdFile = (DorisOrbitProductFile) _productFile; final Record orbitRecord = dorisProdFile.readOrbitData(); OrbitVector orb = null; final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss.SSSSSS"); final ArrayList<OrbitVector> orbitVectorList = new ArrayList<OrbitVector>(); final int numFields = orbitRecord.getNumFields(); for (int i = 0; i < numFields; ++i) { final Field f = orbitRecord.getFieldAt(i); final String fieldName = f.getName(); if (fieldName.contains("blank")) { continue; } else if (fieldName.contains("utc_time")) { orb = new OrbitVector(); try { orb.utcTime = ProductData.UTC.parse(f.getData().getElemString()).getMJD(); } catch (ParseException e) { throw new IllegalFileFormatException("Failed to parse UTC time " + e.getMessage()); } } else if (fieldName.contains("delta_ut1")) { if (orb != null) orb.delta_ut1 = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("abs_orbit")) { if (orb != null) orb.absOrbit = Integer.parseInt(f.getData().getElemString().replace("+", "")); } else if (fieldName.contains("x_pos")) { if (orb != null) orb.xPos = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("y_pos")) { if (orb != null) orb.yPos = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("z_pos")) { if (orb != null) orb.zPos = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("x_vel")) { if (orb != null) orb.xVel = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("y_vel")) { if (orb != null) orb.yVel = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("z_vel")) { if (orb != null) orb.zVel = Double.parseDouble(f.getData().getElemString()); } else if (fieldName.contains("qual_flags")) { if (orb != null) orb.qualFlags = f.getData().getElemString(); orbitVectorList.add(orb); } } dataRecords = orbitVectorList.toArray(new OrbitVector[orbitVectorList.size()]); recordTimes = new double[dataRecords.length]; for (int i = 0; i < dataRecords.length; i++) { recordTimes[i] = dataRecords[i].utcTime; } } }
/** * Get orbit vector for given UTC time. * * @param utc The UTC time * @throws Exception for incorrect time * @return The orbit vector */ public OrbitVector getOrbitVector(double utc) throws Exception { final int interpOrder = 8; final int nRecords = recordTimes.length; double t0 = recordTimes[0]; double tN = recordTimes[nRecords - 1]; // final int n = Arrays.binarySearch(recordTimes, utc); // binary search not needed, we can pre-compute index for given utc wrt delta, and start/end // time final double tRel = (utc - t0) / (tN - t0) * (nRecords - 1); // data index from 0 final int itRel = (int) Math.max( 1, Math.min(Math.round(tRel) - (interpOrder / 2), (nRecords - 1) - interpOrder)); // indices for populating arrays - Working with 8th Order => 9 points final int n0 = itRel; final int n1 = itRel + 1; final int n2 = itRel + 2; final int n3 = itRel + 3; final int n4 = itRel + 4; // <- closest to interpolation point final int n5 = itRel + 5; final int n6 = itRel + 6; final int n7 = itRel + 7; final int n8 = itRel + 8; // TODO: Verify validity of check for incorrect UTC time in parsing orbit // ....I'm not sure that this check is very smart, and that it would pick up not fully // overlapping arc if (n0 < 0 || n1 < 0 || n2 < 0 || n3 < 0 || n4 < 0 || n5 > nRecords || n6 > nRecords || n7 > nRecords || n8 > nRecords) { throw new Exception("Incorrect UTC time"); } final double[] delta_ut1Array = { dataRecords[n0].delta_ut1, dataRecords[n1].delta_ut1, dataRecords[n2].delta_ut1, dataRecords[n3].delta_ut1, dataRecords[n4].delta_ut1, dataRecords[n5].delta_ut1, dataRecords[n6].delta_ut1, dataRecords[n7].delta_ut1, dataRecords[n8].delta_ut1 }; final double[] xPosArray = { dataRecords[n0].xPos, dataRecords[n1].xPos, dataRecords[n2].xPos, dataRecords[n3].xPos, dataRecords[n4].xPos, dataRecords[n5].xPos, dataRecords[n6].xPos, dataRecords[n7].xPos, dataRecords[n8].xPos }; final double[] yPosArray = { dataRecords[n0].yPos, dataRecords[n1].yPos, dataRecords[n2].yPos, dataRecords[n3].yPos, dataRecords[n4].yPos, dataRecords[n5].yPos, dataRecords[n6].yPos, dataRecords[n7].yPos, dataRecords[n8].yPos }; final double[] zPosArray = { dataRecords[n0].zPos, dataRecords[n1].zPos, dataRecords[n2].zPos, dataRecords[n3].zPos, dataRecords[n4].zPos, dataRecords[n5].zPos, dataRecords[n6].zPos, dataRecords[n7].zPos, dataRecords[n8].zPos }; final double[] xVelArray = { dataRecords[n0].xVel, dataRecords[n1].xVel, dataRecords[n2].xVel, dataRecords[n3].xVel, dataRecords[n4].xVel, dataRecords[n5].xVel, dataRecords[n6].xVel, dataRecords[n7].xVel, dataRecords[n8].xVel }; final double[] yVelArray = { dataRecords[n0].yVel, dataRecords[n1].yVel, dataRecords[n2].yVel, dataRecords[n3].yVel, dataRecords[n4].yVel, dataRecords[n5].yVel, dataRecords[n6].yVel, dataRecords[n7].yVel, dataRecords[n8].yVel }; final double[] zVelArray = { dataRecords[n0].zVel, dataRecords[n1].zVel, dataRecords[n2].zVel, dataRecords[n3].zVel, dataRecords[n4].zVel, dataRecords[n5].zVel, dataRecords[n6].zVel, dataRecords[n7].zVel, dataRecords[n8].zVel }; final OrbitVector orb = new OrbitVector(); double ref = tRel - itRel; orb.utcTime = utc; orb.absOrbit = dataRecords[n1].absOrbit; orb.qualFlags = dataRecords[n1].qualFlags; orb.delta_ut1 = lagrangeEightOrderInterpolation(delta_ut1Array, ref); orb.xPos = lagrangeEightOrderInterpolation(xPosArray, ref); orb.yPos = lagrangeEightOrderInterpolation(yPosArray, ref); orb.zPos = lagrangeEightOrderInterpolation(zPosArray, ref); orb.xVel = lagrangeEightOrderInterpolation(xVelArray, ref); orb.yVel = lagrangeEightOrderInterpolation(yVelArray, ref); orb.zVel = lagrangeEightOrderInterpolation(zVelArray, ref); /* final double dt = (utc - recordTimes[n1]) / (recordTimes[n2] - recordTimes[n1]); final double w0 = w(dt + 1.0); final double w1 = w(dt); final double w2 = w(1.0 - dt); final double w3 = w(2.0 - dt); final OrbitVector orb = new OrbitVector(); orb.utcTime = utc; orb.absOrbit = dataRecords[n1].absOrbit; orb.qualFlags = dataRecords[n1].qualFlags; orb.delta_ut1 = w0*dataRecords[n0].delta_ut1 + w1*dataRecords[n1].delta_ut1 + w2*dataRecords[n2].delta_ut1 + w3*dataRecords[n3].delta_ut1; orb.xPos = w0*dataRecords[n0].xPos + w1*dataRecords[n1].xPos + w2*dataRecords[n2].xPos + w3*dataRecords[n3].xPos; orb.yPos = w0*dataRecords[n0].yPos + w1*dataRecords[n1].yPos + w2*dataRecords[n2].yPos + w3*dataRecords[n3].yPos; orb.zPos = w0*dataRecords[n0].zPos + w1*dataRecords[n1].zPos + w2*dataRecords[n2].zPos + w3*dataRecords[n3].zPos; orb.xVel = w0*dataRecords[n0].xVel + w1*dataRecords[n1].xVel + w2*dataRecords[n2].xVel + w3*dataRecords[n3].xVel; orb.yVel = w0*dataRecords[n0].yVel + w1*dataRecords[n1].yVel + w2*dataRecords[n2].yVel + w3*dataRecords[n3].yVel; orb.zVel = w0*dataRecords[n0].zVel + w1*dataRecords[n1].zVel + w2*dataRecords[n2].zVel + w3*dataRecords[n3].zVel; */ return orb; }