<commit_before>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is licensed under the Apache License, Version 2.0 (the
//  "License"); you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__


/// \file wv_correct.cc
///

// Correct CCD artifacts in WorldView 1 and 2 images with given TDI.

// The problem: A WV image is obtained by mosaicking from left to
// right image blocks which are as tall is the entire image (each
// block comes from an individual CCD image sensor). Blocks are
// slightly misplaced in respect to each other by some unknown
// subpixel offset. The goal of this tool is to locate these CCD
// artifact boundary locations, and undo the offsets.
// 

// Observations:
// 1. The CCD artifact locations are periodic, but the starting offset
//    is not positioned at exactly one period. It is less by one fixed
//    value which we name 'shift'.  
// 2. There are CCD offsets in both x and y at each location.
// 3. The magnitude of all CCD offsets in x is the same, but their sign
//    alternates. The same is true in y.
// 4. The period of CCD offsets is inversely proportional to the detector
//    pitch.
// 5. The CCD offsets are pretty consistent among all images of given
//    scan direction (forward or reverse).
// We used all these and a lot of images to heuristically find the
// period and offset of the artifacts, and the 'shift' value. We
// correct these below. We allow the user to override the value of CCD
// offsets if desired.

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Cartography.h>
#include <vw/Math.h>
#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>
#include <asp/Sessions/DG/XML.h>
#include <asp/Sessions/RPC/RPCModel.h>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/PlatformUtils.hpp>

namespace po = boost::program_options;
using namespace vw;
using namespace asp;
using namespace vw::cartography;
using namespace xercesc;
using namespace std;

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  typedef Vector<float64,6> Vector6;
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
  template<> struct PixelFormatID<Vector3f>  { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
  template<> struct PixelFormatID<Vector4>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_4_CHANNEL; };
  template<> struct PixelFormatID<Vector6>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_6_CHANNEL; };
}

struct Options : asp::BaseOptions {
  std::string camera_image_file, camera_model_file, output_image; 
};

void handle_arguments( int argc, char *argv[], Options& opt ) {
  
  po::options_description general_options("");
  general_options.add( asp::BaseOptionsDescription(opt) );
  
  po::options_description positional("");
  positional.add_options()
    ("camera-image", po::value(&opt.camera_image_file))
    ("camera-model", po::value(&opt.camera_model_file))
    ("output-image", po::value(&opt.output_image));
  
  po::positional_options_description positional_desc;
  positional_desc.add("camera-image",1);
  positional_desc.add("camera-model",1);
  positional_desc.add("output-image",1);
  
  std::string usage("[options] <camera-image> <camera-model> <output-image>");
  po::variables_map vm =
    asp::check_command_line( argc, argv, opt, general_options, general_options,
                             positional, positional_desc, usage );

  if ( !vm.count("camera-image") || !vm.count("camera-model") || !vm.count("output-image") )
    vw_throw( ArgumentErr() << "Requires <camera-image>, <camera-model> and <output-image> "
              << "in order to proceed.\n\n"
              << usage << general_options );

  asp::create_out_dir(opt.output_image);
  
}

void arr_to_vec(double arr[], int len, vector<double> & vec){
  vec.clear();
  for (int i = 0; i < len; i++) vec.push_back(arr[i]);
}

void get_offsets(int tdi, bool is_wv01, bool is_forward,
                 std::vector<double> & posx, std::vector<double> & ccdx,
                 std::vector<double> & posy, std::vector<double> & ccdy
                 ){

  // Here we tabulate all ccds offsets and their column pixel positions.
  if (!is_wv01){
  }else{
    if (is_forward){
      if (tdi == 8){
        
        double posx_arr[] = {6.9000000000000000e+02,1.3820000000000000e+03,2.0770000000000000e+03,2.7720000000000000e+03,3.4670000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5670000000000000e+03,6.2680000000000000e+03,6.9720000000000000e+03,7.6750000000000000e+03,8.3790000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0497000000000000e+04,1.1204000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6169000000000000e+04,1.6878000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9009000000000000e+04,1.9725000000000000e+04,2.0435000000000000e+04,2.1141000000000000e+04,2.1875000000000000e+04,2.2579000000000000e+04,2.3267000000000000e+04,2.3975000000000000e+04,2.4683000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8908000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1010000000000000e+04,3.1707000000000000e+04,3.2404000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {0,0,0,0,3.9572899122610738e-01,-0.4,1.3571345876690324e-01,-1.3599568525285227e-01,2.1848597840209738e-01,-1.9302532491443239e-01,1.5373607383106744e-01,-2.7948565111193063e-01,1.8470511522813510e-01,-8.8010620304032103e-02,4.1712154427482312e-01,-1.6133955851477760e-01,1.6782370523021301e-01,-1.9071066562455274e-01,9.4139947899578386e-02,-1.8390507569972631e-01,1.0458337107311372e-01,-1.3184212217192476e-01,1.3748731085111202e-01,-1.6997707746371654e-01,4.0533794015827662e-01,-1.8414617591004279e-01,1.5844241125556013e-01,-1.3291686600523619e-01,1.0204979703149097e-01,-2.0664117331352239e-01,1.8094775320573228e-01,-2.0731801920342768e-01,7.1547167910899323e-02,-1.3458151098218407e-01,1.4946741303774508e-01,-9.1924110765654321e-02,6.8305981753759237e-02,0,0,0,0,0,0,0,0,1.9511982760486032e-01,-2.6781463372201086e-01,2.2508286764347213e-01,-2.1325412224027540e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={6.9000000000000000e+02,1.3820000000000000e+03,2.0770000000000000e+03,2.7720000000000000e+03,3.4670000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5670000000000000e+03,6.2680000000000000e+03,6.9720000000000000e+03,7.6750000000000000e+03,8.3790000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0497000000000000e+04,1.1204000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6169000000000000e+04,1.6878000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9009000000000000e+04,1.9725000000000000e+04,2.0435000000000000e+04,2.1141000000000000e+04,2.1875000000000000e+04,2.2579000000000000e+04,2.3267000000000000e+04,2.3975000000000000e+04,2.4683000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8908000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1010000000000000e+04,3.1707000000000000e+04,3.2404000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {0,0,0,0,2.7737184873656524e-01,-2.5199396985728040e-01,9.2651619425092591e-02,-1.2484085009254375e-01,9.1624371368929466e-02,-1.0163420477660505e-01,-8.5087919020240044e-02,-5.3278003593145037e-02,1.9474828198101091e-01,-5.5653320997682228e-02,1.4105791229907522e-01,-9.7756436532447491e-02,2.3515271743956914e-01,-2.4064621068353220e-01,1.9793293593058281e-01,-3.0417359707178432e-01,3.0974742641785702e-01,-2.8392516950893354e-01,4.3358586437052404e-01,-2.1286311036139788e-01,2.4607083739631108e-01,-2.8247520147602145e-01,3.5719728474354340e-01,-3.6362100039496115e-01,3.7045268711965218e-01,-3.3826985178248126e-01,4.2964452311943979e-01,-3.7778034342534478e-01,3.5082720318556498e-01,-4.6804694273970554e-01,3.2346002285296005e-01,-3.1529610028369914e-01,4.7169816490584404e-01,-4.7766860316648618e-01,4.1307927109971820e-01,-3.4825254544933831e-01,3.6562789909663967e-01,-4.8754456032180638e-01,3.9579963026130471e-01,-3.2165596442784983e-01,3.7812760195170941e-01,-3.8101306006307878e-01,4.9930246080447915e-01,-5.7700807932152287e-01,4.8434239761391673e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);

      }else if (tdi == 16){
        
        double posx_arr[] = {6.2900000000000000e+02,1.3570000000000000e+03,2.0190000000000000e+03,2.7690000000000000e+03,3.4720000000000000e+03,4.1790000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2730000000000000e+03,6.9730000000000000e+03,7.6250000000000000e+03,8.3790000000000000e+03,9.0910000000000000e+03,9.7920000000000000e+03,1.0499000000000000e+04,1.1204000000000000e+04,1.1911000000000000e+04,1.2620000000000000e+04,1.3332000000000000e+04,1.4040000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6170000000000000e+04,1.6879000000000000e+04,1.7591000000000000e+04,1.8300000000000000e+04,1.9008000000000000e+04,1.9720000000000000e+04,2.0426000000000000e+04,2.1141000000000000e+04,2.1848000000000000e+04,2.2559000000000000e+04,2.3271000000000000e+04,2.3977000000000000e+04,2.4682000000000000e+04,2.5419000000000000e+04,2.6095000000000000e+04,2.6803000000000000e+04,2.7446000000000000e+04,2.8302000000000000e+04,2.8908000000000000e+04,2.9608000000000000e+04,3.0313000000000000e+04,3.1009000000000000e+04,3.1705000000000000e+04,3.2406000000000000e+04,3.3100000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {6.7322551801454480e-02,5.5941279131803634e-02,-6.3757124794674186e-02,-6.8350222655965132e-02,1.7691659140427704e-01,-6.5546000611674385e-02,6.3907733085781446e-02,-9.4966625926268172e-02,9.4161850926099605e-02,-1.0542259530055144e-01,-8.1558061694499709e-02,-6.3956300595019416e-02,4.1564490770397769e-02,-6.0005436499402910e-02,2.7687811096602116e-01,-6.7650615566507560e-02,8.9531829438824359e-02,-7.5787800987529685e-02,6.0918450645685199e-02,-4.9435252430723518e-02,7.8217062959282352e-02,-9.4972312086564092e-02,6.8771948144368461e-02,-5.5916563953937647e-02,2.5576397858317801e-01,-6.2953016311800947e-02,4.5986274236245760e-02,-5.2151312380337433e-02,3.5461672386768096e-02,-7.8840968976700190e-02,5.8279888571948685e-02,-5.6318493405969880e-02,-2.3130788594668883e-02,-2.5727892445735229e-02,6.7618551931374907e-02,-3.2635798235672329e-02,-6.7421171442540700e-02,8.6289010551310996e-02,-4.2940282592809562e-02,-6.7487297331515511e-02,-1.6954569447987194e-01,1.5768945188280239e-01,-1.3197137444641416e-01,2.2044168881490209e-01,-1.7686345973293444e-01,2.8571073037673689e-01,-2.5204743971722710e-01,2.9477986650443111e-01,-3.1357641656875035e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={5.5700000000000000e+02,1.3840000000000000e+03,2.0790000000000000e+03,2.7720000000000000e+03,4.9010000000000000e+03,5.6020000000000000e+03,6.8740000000000000e+03,7.6810000000000000e+03,8.3770000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0500000000000000e+04,1.1206000000000000e+04,1.1914000000000000e+04,1.2623000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4749000000000000e+04,1.5459000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9722000000000000e+04,2.0431000000000000e+04,2.1140000000000000e+04,2.1851000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3976000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6800000000000000e+04,2.7503000000000000e+04,2.8206000000000000e+04,2.8909000000000000e+04,2.9611000000000000e+04,3.0309000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2401000000000000e+04,3.3098000000000000e+04,3.3791000000000000e+04,3.4482000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {5.2874163366164850e-02,1.4813114779561809e-01,-1.3228522060801995e-01,5.1229840789382905e-02,4.1734055216619194e-02,-3.4922349728371403e-02,2.3489411511399848e-02,8.0756339158257071e-02,-4.1430846518602682e-02,1.3825891634375403e-01,-1.0281921942927558e-01,1.8102049531293241e-01,-1.4505660180914340e-01,1.8186344173432878e-01,-1.8620316464758269e-01,1.9090650984864999e-01,-2.8086787970093174e-01,2.7066109799278149e-01,-2.2564204861733023e-01,3.2153128507658019e-01,-2.5708859257733496e-01,2.6364737894970347e-01,-2.8693208660602365e-01,2.7970516529790845e-01,-3.5311023659542107e-01,3.4701280163120907e-01,-3.1032664634310730e-01,3.5125263768893017e-01,-3.3322268782288833e-01,3.6955614181826035e-01,-3.3683473663931718e-01,3.2182908581461295e-01,-2.8261547868377229e-01,3.4742873160768417e-01,-2.9435215444692314e-01,3.0697747027458971e-01,-2.9547216462701609e-01,3.2267414829365171e-01,-3.4291155301037418e-01,2.8631768612226638e-01,-2.6625338683543259e-01,3.4282658200878574e-01,-2.5735046181265991e-01,2.6016063755950836e-01,-2.7861330621270186e-01,2.4248759221995142e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);

      }else if (tdi == 32){
        
         double posx_arr[] = {6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7730000000000000e+03,3.4580000000000000e+03,4.1690000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2700000000000000e+03,6.9720000000000000e+03,7.6770000000000000e+03,8.3800000000000000e+03,9.0860000000000000e+03,9.7920000000000000e+03,1.0505000000000000e+04,1.1206000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7591000000000000e+04,1.8301000000000000e+04,1.9012000000000000e+04,1.9720000000000000e+04,2.0432000000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266000000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3099000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
         arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
         double ccdx_arr[] = {-1.5815654418563752e-01,1.3826350530962050e-01,-1.6016106928636276e-01,1.7292351786151797e-01,-8.4251284556116038e-02,1.3523902369157348e-01,-1.3545886295780737e-01,1.3984628576111927e-01,-8.1532674525840704e-02,9.4697680166625067e-02,-1.0592758885259967e-01,4.6579834981628057e-02,-8.2313118665729212e-02,1.2002910740140957e-01,-1.5536100300284500e-02,9.5570826053090252e-02,-8.5935714547473396e-02,7.1701504496924306e-02,-4.8261551539294886e-02,1.0887016101633357e-01,-6.0376640338178925e-02,5.0426384764782284e-02,-7.4629150917886147e-02,7.3333337683582994e-02,1.3473731928967686e-02,5.9902243380629411e-02,-1.0637719830921741e-01,1.2901431398998836e-01,-6.7279387139093816e-02,8.6465589898355108e-02,-7.9828628987704930e-02,1.0291510265774768e-01,-1.0434449874621080e-01,1.2679075861184977e-01,-4.1769763304420532e-02,1.8653481213510253e-01,-2.0958544403438775e-01,1.9791028244010830e-01,-2.4696221386197473e-01,2.2895773820335324e-01,-1.7850291944712204e-01,1.8711950573480507e-01,-3.3754429964928234e-01,2.5821884129030215e-01,-2.0434256714964005e-01,4.1418566014699210e-01,-3.9931658359979100e-01,3.7510088116850077e-01,-4.1403543054361425e-01};
         arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
         double posy_arr[] ={6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7740000000000000e+03,3.4575000000000000e+03,4.1680000000000000e+03,4.8660000000000000e+03,5.5670000000000000e+03,6.2710000000000000e+03,6.9730000000000000e+03,7.4430000000000000e+03,8.4860000000000000e+03,9.1100000000000000e+03,9.7920000000000000e+03,1.0498000000000000e+04,1.1207000000000000e+04,1.1914000000000000e+04,1.2622000000000000e+04,1.3329000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6880000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9720000000000000e+04,2.0430000000000000e+04,2.1141000000000000e+04,2.1850000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3974000000000000e+04,2.4681000000000000e+04,2.5389000000000000e+04,2.6094000000000000e+04,2.6797000000000000e+04,2.7501000000000000e+04,2.8238000000000000e+04,2.8896000000000000e+04,2.9710000000000000e+04,3.0106000000000000e+04,3.1007000000000000e+04,3.1552000000000000e+04,3.2402000000000000e+04,3.3097000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
         arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
         double ccdy_arr[] = {-2.5679384780785375e-01,2.1132524108212025e-01,-1.9890929041258171e-01,1.6743466645971244e-01,-3.0290900802832363e-02,1.2520084986428626e-01,-6.6310853481927404e-02,9.7787759335348293e-02,-4.7026742606632993e-02,-4.0719397722168357e-02,3.3620546875873569e-02,-3.0102129563891310e-02,5.1037911282746602e-02,-4.0388786002217299e-02,4.8061714461599923e-02,-5.5895642605816913e-02,7.1314129810702370e-02,-7.6604178475669069e-02,9.7449063613589945e-02,-1.0828765871885951e-01,1.1363625166513155e-01,-1.2841434371486909e-01,1.1913396821174335e-01,-1.6093971470699187e-01,1.6679734496194806e-01,-1.9561240122110690e-01,1.4561399603445646e-01,-1.8834366060830782e-01,1.4779996646048937e-01,-1.6694224556665363e-01,1.6887551340374002e-01,-1.6896325192069545e-01,1.7280986149540695e-01,-1.7481150806231555e-01,1.8974131057032312e-01,-1.6203523746941276e-01,1.2895698177790360e-01,-1.2814173545280660e-01,1.3614836986578066e-01,-1.5894266097567594e-01,1.4865193671756302e-01,-1.1977251781868413e-01,1.3054339999410874e-01,-9.6750535696703138e-02,1.6842720636109526e-01,-8.2351842567259040e-02,-5.9741317509331537e-02,-7.4004189893254774e-02,-6.0371436981168827e-02};
         arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);
        
      }else if (tdi == 48){
        
        double posx_arr[] = {6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7730000000000000e+03,3.4580000000000000e+03,4.1690000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2700000000000000e+03,6.9720000000000000e+03,7.6770000000000000e+03,8.3800000000000000e+03,9.0860000000000000e+03,9.7920000000000000e+03,1.0505000000000000e+04,1.1206000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7591000000000000e+04,1.8301000000000000e+04,1.9012000000000000e+04,1.9720000000000000e+04,2.0432000000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266000000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3099000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {-3.2946263385876073e-01,2.6822672303060707e-01,-2.7219800277644979e-01,3.2114706103684659e-01,-1.1264051193844726e-01,2.1650365243094197e-01,-2.9850534257863964e-01,2.4690262924579376e-01,-3.0264558267838221e-01,1.9002513807042659e-01,-2.2269004121580999e-01,1.9360526493221386e-01,-2.4333024293404595e-01,2.3253426572925068e-01,2.5156939346654091e-02,2.3240995046557339e-01,-2.2672903386601889e-01,1.5590477088799856e-01,-1.5002686187069883e-01,2.0344831295675106e-01,-1.5000864041927442e-01,1.8004430049333014e-01,-1.8236695292080785e-01,1.8325510525277885e-01,3.3572343456822654e-02,1.6768958115164090e-01,-1.7656399543377982e-01,1.9586089774158649e-01,-1.7984311406510889e-01,1.9926780777821917e-01,-2.0358163540196328e-01,1.8788400881417389e-01,-2.6839931133109096e-01,2.4275915958519964e-01,-1.9419370826317078e-01,2.3213640634391663e-01,-2.0322722705876156e-01,2.5395023204178102e-01,-3.1352589198440872e-01,2.8813130768645712e-01,-3.2571760506100766e-01,3.7344440543148194e-01,-3.2440667961683478e-01,4.4966322933102876e-01,-3.5284854392228138e-01,4.5498566236612847e-01,-4.6890882370639664e-01,5.3253439420167337e-01,-5.1690187379933494e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7740000000000000e+03,3.4575000000000000e+03,4.1680000000000000e+03,4.8660000000000000e+03,5.5670000000000000e+03,6.2710000000000000e+03,6.9730000000000000e+03,7.4430000000000000e+03,8.4860000000000000e+03,9.1100000000000000e+03,9.7920000000000000e+03,1.0498000000000000e+04,1.1207000000000000e+04,1.1914000000000000e+04,1.2622000000000000e+04,1.3329000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6880000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9720000000000000e+04,2.0430000000000000e+04,2.1141000000000000e+04,2.1850000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3974000000000000e+04,2.4681000000000000e+04,2.5389000000000000e+04,2.6094000000000000e+04,2.6797000000000000e+04,2.7501000000000000e+04,2.8238000000000000e+04,2.8896000000000000e+04,2.9710000000000000e+04,3.0106000000000000e+04,3.1007000000000000e+04,3.1552000000000000e+04,3.2402000000000000e+04,3.3097000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {-1.9855267108725011e-01,1.7955082108595999e-01,-1.8827745225040018e-01,1.3932648815497944e-01,-6.0352542704901455e-02,8.3598970550751980e-02,-8.1175104051077959e-02,6.1423375459795058e-02,-4.5004799966324879e-02,5.1255915991506043e-02,1.5851812214634477e-02,1.5587369184767868e-02,1.2194157289131528e-02,-3.3985901939564599e-02,7.0922061628214295e-02,-5.3223665244117681e-02,3.8875501918710656e-02,-5.5471377905873670e-02,5.3105759125309210e-02,-9.9237321842864795e-02,6.2515982392321895e-02,-8.4411396949582967e-02,8.7660527700112317e-02,-9.7615657244219792e-02,1.1887807394615302e-01,-1.0116151698982925e-01,9.2884382992062239e-02,-9.0252420387025509e-02,8.8929836687679620e-02,-1.0833431823799911e-01,8.0427361987862905e-02,-8.8225813952202234e-02,6.7822547934654032e-02,-8.6349198150212400e-02,8.7246760279810182e-02,-7.0883233135712959e-02,4.1376134151766455e-02,-3.5761138416796644e-02,3.7183085174551947e-02,-1.8063316353517003e-02,2.0949603842599852e-02,-2.4268409874204040e-02,-2.2141072979198307e-02,3.0889019160442014e-02,3.4287549363534349e-02,7.0188151962212772e-02,-6.9597035784645517e-02,9.1561840117775795e-02,-1.4346661758051732e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);
        
      }else if (tdi == 56){
        
        double posx_arr[] = {6.9050000000000000e+02,1.3830000000000000e+03,2.0775000000000000e+03,2.7725000000000000e+03,3.4635000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2695000000000000e+03,6.9720000000000000e+03,7.6765000000000000e+03,8.3800000000000000e+03,9.0845000000000000e+03,9.7915000000000000e+03,1.0502500000000000e+04,1.1205500000000000e+04,1.1913500000000000e+04,1.2621500000000000e+04,1.3330500000000000e+04,1.4040500000000000e+04,1.4749500000000000e+04,1.5460000000000000e+04,1.6169500000000000e+04,1.6880500000000000e+04,1.7590500000000000e+04,1.8301000000000000e+04,1.9011500000000000e+04,1.9720500000000000e+04,2.0431500000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266500000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6798500000000000e+04,2.7502500000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610500000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4483500000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {-3.5011442399307202e-01,3.1186407063727184e-01,-3.2335982284254117e-01,3.5688803627847732e-01,-1.5016902336398030e-01,2.7091922018898873e-01,-3.4524579685389989e-01,3.1697476178278094e-01,-3.3427642010528191e-01,2.4348731667372364e-01,-2.5459010039954394e-01,2.2227864965341840e-01,-2.4963564133255550e-01,2.6519143229617087e-01,-1.2640033051156893e-02,2.6926418565530419e-01,-2.6413094069459742e-01,1.7933663392775823e-01,-1.7857720325097262e-01,2.3227298026241555e-01,-1.8833606658120045e-01,2.0690430915056696e-01,-2.2153185513515222e-01,2.2470157361209891e-01,-1.0775858639518222e-02,1.9409607914016191e-01,-1.9017563481638641e-01,2.0941570156418010e-01,-1.9959115270537459e-01,2.3450585103367219e-01,-2.4346167898401047e-01,2.3507302665020746e-01,-2.9839629178583321e-01,2.8796840809065738e-01,-2.2339992370188613e-01,2.6676508093280049e-01,-2.2822730588765003e-01,2.7316283112057416e-01,-3.4718648441520028e-01,3.2886139038062245e-01,-3.1213617802392812e-01,4.1015850839081253e-01,-3.6843147363566531e-01,4.4417245109948189e-01,-3.4664171603617239e-01,4.8513123485069182e-01,-4.9177442050887177e-01,5.5564212715312777e-01,-5.1330089584066618e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        <commit_msg>wv_correct: Improve correctins for TDI 32<commit_after>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2013, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is licensed under the Apache License, Version 2.0 (the
//  "License"); you may not use this file except in compliance with the
//  License. You may obtain a copy of the License at
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// __END_LICENSE__


/// \file wv_correct.cc
///

// Correct CCD artifacts in WorldView 1 and 2 images with given TDI.

// The problem: A WV image is obtained by mosaicking from left to
// right image blocks which are as tall is the entire image (each
// block comes from an individual CCD image sensor). Blocks are
// slightly misplaced in respect to each other by some unknown
// subpixel offset. The goal of this tool is to locate these CCD
// artifact boundary locations, and undo the offsets.
// 

// Observations:
// 1. The CCD artifact locations are periodic, but the starting offset
//    is not positioned at exactly one period. It is less by one fixed
//    value which we name 'shift'.  
// 2. There are CCD offsets in both x and y at each location.
// 3. The magnitude of all CCD offsets in x is the same, but their sign
//    alternates. The same is true in y.
// 4. The period of CCD offsets is inversely proportional to the detector
//    pitch.
// 5. The CCD offsets are pretty consistent among all images of given
//    scan direction (forward or reverse).
// We used all these and a lot of images to heuristically find the
// period and offset of the artifacts, and the 'shift' value. We
// correct these below. We allow the user to override the value of CCD
// offsets if desired.

#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Cartography.h>
#include <vw/Math.h>
#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>
#include <asp/Sessions/DG/XML.h>
#include <asp/Sessions/RPC/RPCModel.h>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/PlatformUtils.hpp>

namespace po = boost::program_options;
using namespace vw;
using namespace asp;
using namespace vw::cartography;
using namespace xercesc;
using namespace std;

// Allows FileIO to correctly read/write these pixel types
namespace vw {
  typedef Vector<float64,6> Vector6;
  template<> struct PixelFormatID<Vector3>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
  template<> struct PixelFormatID<Vector3f>  { static const PixelFormatEnum value = VW_PIXEL_GENERIC_3_CHANNEL; };
  template<> struct PixelFormatID<Vector4>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_4_CHANNEL; };
  template<> struct PixelFormatID<Vector6>   { static const PixelFormatEnum value = VW_PIXEL_GENERIC_6_CHANNEL; };
}

struct Options : asp::BaseOptions {
  std::string camera_image_file, camera_model_file, output_image; 
};

void handle_arguments( int argc, char *argv[], Options& opt ) {
  
  po::options_description general_options("");
  general_options.add( asp::BaseOptionsDescription(opt) );
  
  po::options_description positional("");
  positional.add_options()
    ("camera-image", po::value(&opt.camera_image_file))
    ("camera-model", po::value(&opt.camera_model_file))
    ("output-image", po::value(&opt.output_image));
  
  po::positional_options_description positional_desc;
  positional_desc.add("camera-image",1);
  positional_desc.add("camera-model",1);
  positional_desc.add("output-image",1);
  
  std::string usage("[options] <camera-image> <camera-model> <output-image>");
  po::variables_map vm =
    asp::check_command_line( argc, argv, opt, general_options, general_options,
                             positional, positional_desc, usage );

  if ( !vm.count("camera-image") || !vm.count("camera-model") || !vm.count("output-image") )
    vw_throw( ArgumentErr() << "Requires <camera-image>, <camera-model> and <output-image> "
              << "in order to proceed.\n\n"
              << usage << general_options );

  asp::create_out_dir(opt.output_image);
  
}

void arr_to_vec(double arr[], int len, vector<double> & vec){
  vec.clear();
  for (int i = 0; i < len; i++) vec.push_back(arr[i]);
}

void get_offsets(int tdi, bool is_wv01, bool is_forward,
                 std::vector<double> & posx, std::vector<double> & ccdx,
                 std::vector<double> & posy, std::vector<double> & ccdy
                 ){

  // Here we tabulate all ccds offsets and their column pixel positions.
  if (!is_wv01){
  }else{
    if (is_forward){
      if (tdi == 8){
        
        double posx_arr[] = {6.9000000000000000e+02,1.3820000000000000e+03,2.0770000000000000e+03,2.7720000000000000e+03,3.4670000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5670000000000000e+03,6.2680000000000000e+03,6.9720000000000000e+03,7.6750000000000000e+03,8.3790000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0497000000000000e+04,1.1204000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6169000000000000e+04,1.6878000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9009000000000000e+04,1.9725000000000000e+04,2.0435000000000000e+04,2.1141000000000000e+04,2.1875000000000000e+04,2.2579000000000000e+04,2.3267000000000000e+04,2.3975000000000000e+04,2.4683000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8908000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1010000000000000e+04,3.1707000000000000e+04,3.2404000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {0,0,0,0,3.9572899122610738e-01,-0.4,1.3571345876690324e-01,-1.3599568525285227e-01,2.1848597840209738e-01,-1.9302532491443239e-01,1.5373607383106744e-01,-2.7948565111193063e-01,1.8470511522813510e-01,-8.8010620304032103e-02,4.1712154427482312e-01,-1.6133955851477760e-01,1.6782370523021301e-01,-1.9071066562455274e-01,9.4139947899578386e-02,-1.8390507569972631e-01,1.0458337107311372e-01,-1.3184212217192476e-01,1.3748731085111202e-01,-1.6997707746371654e-01,4.0533794015827662e-01,-1.8414617591004279e-01,1.5844241125556013e-01,-1.3291686600523619e-01,1.0204979703149097e-01,-2.0664117331352239e-01,1.8094775320573228e-01,-2.0731801920342768e-01,7.1547167910899323e-02,-1.3458151098218407e-01,1.4946741303774508e-01,-9.1924110765654321e-02,6.8305981753759237e-02,0,0,0,0,0,0,0,0,1.9511982760486032e-01,-2.6781463372201086e-01,2.2508286764347213e-01,-2.1325412224027540e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={6.9000000000000000e+02,1.3820000000000000e+03,2.0770000000000000e+03,2.7720000000000000e+03,3.4670000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5670000000000000e+03,6.2680000000000000e+03,6.9720000000000000e+03,7.6750000000000000e+03,8.3790000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0497000000000000e+04,1.1204000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6169000000000000e+04,1.6878000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9009000000000000e+04,1.9725000000000000e+04,2.0435000000000000e+04,2.1141000000000000e+04,2.1875000000000000e+04,2.2579000000000000e+04,2.3267000000000000e+04,2.3975000000000000e+04,2.4683000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8908000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1010000000000000e+04,3.1707000000000000e+04,3.2404000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {0,0,0,0,2.7737184873656524e-01,-2.5199396985728040e-01,9.2651619425092591e-02,-1.2484085009254375e-01,9.1624371368929466e-02,-1.0163420477660505e-01,-8.5087919020240044e-02,-5.3278003593145037e-02,1.9474828198101091e-01,-5.5653320997682228e-02,1.4105791229907522e-01,-9.7756436532447491e-02,2.3515271743956914e-01,-2.4064621068353220e-01,1.9793293593058281e-01,-3.0417359707178432e-01,3.0974742641785702e-01,-2.8392516950893354e-01,4.3358586437052404e-01,-2.1286311036139788e-01,2.4607083739631108e-01,-2.8247520147602145e-01,3.5719728474354340e-01,-3.6362100039496115e-01,3.7045268711965218e-01,-3.3826985178248126e-01,4.2964452311943979e-01,-3.7778034342534478e-01,3.5082720318556498e-01,-4.6804694273970554e-01,3.2346002285296005e-01,-3.1529610028369914e-01,4.7169816490584404e-01,-4.7766860316648618e-01,4.1307927109971820e-01,-3.4825254544933831e-01,3.6562789909663967e-01,-4.8754456032180638e-01,3.9579963026130471e-01,-3.2165596442784983e-01,3.7812760195170941e-01,-3.8101306006307878e-01,4.9930246080447915e-01,-5.7700807932152287e-01,4.8434239761391673e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);

      }else if (tdi == 16){
        
        double posx_arr[] = {6.2900000000000000e+02,1.3570000000000000e+03,2.0190000000000000e+03,2.7690000000000000e+03,3.4720000000000000e+03,4.1790000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2730000000000000e+03,6.9730000000000000e+03,7.6250000000000000e+03,8.3790000000000000e+03,9.0910000000000000e+03,9.7920000000000000e+03,1.0499000000000000e+04,1.1204000000000000e+04,1.1911000000000000e+04,1.2620000000000000e+04,1.3332000000000000e+04,1.4040000000000000e+04,1.4750000000000000e+04,1.5459000000000000e+04,1.6170000000000000e+04,1.6879000000000000e+04,1.7591000000000000e+04,1.8300000000000000e+04,1.9008000000000000e+04,1.9720000000000000e+04,2.0426000000000000e+04,2.1141000000000000e+04,2.1848000000000000e+04,2.2559000000000000e+04,2.3271000000000000e+04,2.3977000000000000e+04,2.4682000000000000e+04,2.5419000000000000e+04,2.6095000000000000e+04,2.6803000000000000e+04,2.7446000000000000e+04,2.8302000000000000e+04,2.8908000000000000e+04,2.9608000000000000e+04,3.0313000000000000e+04,3.1009000000000000e+04,3.1705000000000000e+04,3.2406000000000000e+04,3.3100000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {6.7322551801454480e-02,5.5941279131803634e-02,-6.3757124794674186e-02,-6.8350222655965132e-02,1.7691659140427704e-01,-6.5546000611674385e-02,6.3907733085781446e-02,-9.4966625926268172e-02,9.4161850926099605e-02,-1.0542259530055144e-01,-8.1558061694499709e-02,-6.3956300595019416e-02,4.1564490770397769e-02,-6.0005436499402910e-02,2.7687811096602116e-01,-6.7650615566507560e-02,8.9531829438824359e-02,-7.5787800987529685e-02,6.0918450645685199e-02,-4.9435252430723518e-02,7.8217062959282352e-02,-9.4972312086564092e-02,6.8771948144368461e-02,-5.5916563953937647e-02,2.5576397858317801e-01,-6.2953016311800947e-02,4.5986274236245760e-02,-5.2151312380337433e-02,3.5461672386768096e-02,-7.8840968976700190e-02,5.8279888571948685e-02,-5.6318493405969880e-02,-2.3130788594668883e-02,-2.5727892445735229e-02,6.7618551931374907e-02,-3.2635798235672329e-02,-6.7421171442540700e-02,8.6289010551310996e-02,-4.2940282592809562e-02,-6.7487297331515511e-02,-1.6954569447987194e-01,1.5768945188280239e-01,-1.3197137444641416e-01,2.2044168881490209e-01,-1.7686345973293444e-01,2.8571073037673689e-01,-2.5204743971722710e-01,2.9477986650443111e-01,-3.1357641656875035e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={5.5700000000000000e+02,1.3840000000000000e+03,2.0790000000000000e+03,2.7720000000000000e+03,4.9010000000000000e+03,5.6020000000000000e+03,6.8740000000000000e+03,7.6810000000000000e+03,8.3770000000000000e+03,9.0860000000000000e+03,9.7910000000000000e+03,1.0500000000000000e+04,1.1206000000000000e+04,1.1914000000000000e+04,1.2623000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4749000000000000e+04,1.5459000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9722000000000000e+04,2.0431000000000000e+04,2.1140000000000000e+04,2.1851000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3976000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6800000000000000e+04,2.7503000000000000e+04,2.8206000000000000e+04,2.8909000000000000e+04,2.9611000000000000e+04,3.0309000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2401000000000000e+04,3.3098000000000000e+04,3.3791000000000000e+04,3.4482000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {5.2874163366164850e-02,1.4813114779561809e-01,-1.3228522060801995e-01,5.1229840789382905e-02,4.1734055216619194e-02,-3.4922349728371403e-02,2.3489411511399848e-02,8.0756339158257071e-02,-4.1430846518602682e-02,1.3825891634375403e-01,-1.0281921942927558e-01,1.8102049531293241e-01,-1.4505660180914340e-01,1.8186344173432878e-01,-1.8620316464758269e-01,1.9090650984864999e-01,-2.8086787970093174e-01,2.7066109799278149e-01,-2.2564204861733023e-01,3.2153128507658019e-01,-2.5708859257733496e-01,2.6364737894970347e-01,-2.8693208660602365e-01,2.7970516529790845e-01,-3.5311023659542107e-01,3.4701280163120907e-01,-3.1032664634310730e-01,3.5125263768893017e-01,-3.3322268782288833e-01,3.6955614181826035e-01,-3.3683473663931718e-01,3.2182908581461295e-01,-2.8261547868377229e-01,3.4742873160768417e-01,-2.9435215444692314e-01,3.0697747027458971e-01,-2.9547216462701609e-01,3.2267414829365171e-01,-3.4291155301037418e-01,2.8631768612226638e-01,-2.6625338683543259e-01,3.4282658200878574e-01,-2.5735046181265991e-01,2.6016063755950836e-01,-2.7861330621270186e-01,2.4248759221995142e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);

      }else if (tdi == 32){
        
         double posx_arr[] = {6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7730000000000000e+03,3.4580000000000000e+03,4.1690000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2700000000000000e+03,6.9720000000000000e+03,7.6770000000000000e+03,8.3800000000000000e+03,9.0860000000000000e+03,9.7920000000000000e+03,1.0505000000000000e+04,1.1206000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7591000000000000e+04,1.8301000000000000e+04,1.9012000000000000e+04,1.9720000000000000e+04,2.0432000000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266000000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3099000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
         arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
         double ccdx_arr[] = {-1.5815654418563752e-01,1.3826350530962050e-01,-1.6016106928636276e-01,1.7292351786151797e-01,-8.4251284556116038e-02,1.3523902369157348e-01,-1.3545886295780737e-01,1.3984628576111927e-01,-8.1532674525840704e-02,9.4697680166625067e-02,-1.0592758885259967e-01,4.6579834981628057e-02,-8.2313118665729212e-02,1.2002910740140957e-01,1.5536100300284500e-01,9.5570826053090252e-02,-8.5935714547473396e-02,7.1701504496924306e-02,-4.8261551539294886e-02,1.0887016101633357e-01,-6.0376640338178925e-02,5.0426384764782284e-02,-7.4629150917886147e-02,7.3333337683582994e-02,1.3473731928967686e-01,5.9902243380629411e-02,-1.0637719830921741e-01,1.2901431398998836e-01,-6.7279387139093816e-02,8.6465589898355108e-02,-7.9828628987704930e-02,1.0291510265774768e-01,-1.0434449874621080e-01,1.2679075861184977e-01,-4.1769763304420532e-02,1.8653481213510253e-01,-2.0958544403438775e-01,1.9791028244010830e-01,-2.4696221386197473e-01,2.2895773820335324e-01,-1.7850291944712204e-01,1.8711950573480507e-01,-3.3754429964928234e-01,2.5821884129030215e-01,-2.0434256714964005e-01,4.1418566014699210e-01,-3.9931658359979100e-01,3.7510088116850077e-01,-4.1403543054361425e-01};
         arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
         double posy_arr[] ={6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7740000000000000e+03,3.4575000000000000e+03,4.1680000000000000e+03,4.8660000000000000e+03,5.5670000000000000e+03,6.2710000000000000e+03,6.9730000000000000e+03,7.4430000000000000e+03,8.4860000000000000e+03,9.1100000000000000e+03,9.7920000000000000e+03,1.0498000000000000e+04,1.1207000000000000e+04,1.1914000000000000e+04,1.2622000000000000e+04,1.3329000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6880000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9720000000000000e+04,2.0430000000000000e+04,2.1141000000000000e+04,2.1850000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3974000000000000e+04,2.4681000000000000e+04,2.5389000000000000e+04,2.6094000000000000e+04,2.6797000000000000e+04,2.7501000000000000e+04,2.8238000000000000e+04,2.8896000000000000e+04,2.9710000000000000e+04,3.0106000000000000e+04,3.1007000000000000e+04,3.1552000000000000e+04,3.2402000000000000e+04,3.3097000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
         arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
         double ccdy_arr[] = {-2.5679384780785375e-01,2.1132524108212025e-01,-1.9890929041258171e-01,1.6743466645971244e-01,-3.0290900802832363e-02,1.2520084986428626e-01,-6.6310853481927404e-02,9.7787759335348293e-02,-4.7026742606632993e-02,-4.0719397722168357e-02,3.3620546875873569e-02,-3.0102129563891310e-02,5.1037911282746602e-02,-4.0388786002217299e-02,4.8061714461599923e-02,-5.5895642605816913e-02,7.1314129810702370e-02,-7.6604178475669069e-02,9.7449063613589945e-02,-1.0828765871885951e-01,1.1363625166513155e-01,-1.2841434371486909e-01,1.1913396821174335e-01,-1.6093971470699187e-01,1.6679734496194806e-01,-1.9561240122110690e-01,1.4561399603445646e-01,-1.8834366060830782e-01,1.4779996646048937e-01,-1.6694224556665363e-01,1.6887551340374002e-01,-1.6896325192069545e-01,1.7280986149540695e-01,-1.7481150806231555e-01,1.8974131057032312e-01,-1.6203523746941276e-01,1.2895698177790360e-01,-1.2814173545280660e-01,1.3614836986578066e-01,-1.5894266097567594e-01,1.4865193671756302e-01,-1.1977251781868413e-01,1.3054339999410874e-01,-9.6750535696703138e-02,1.6842720636109526e-01,-8.2351842567259040e-02,-5.9741317509331537e-02,-7.4004189893254774e-02,-6.0371436981168827e-02};
         arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);
        
      }else if (tdi == 48){
        
        double posx_arr[] = {6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7730000000000000e+03,3.4580000000000000e+03,4.1690000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2700000000000000e+03,6.9720000000000000e+03,7.6770000000000000e+03,8.3800000000000000e+03,9.0860000000000000e+03,9.7920000000000000e+03,1.0505000000000000e+04,1.1206000000000000e+04,1.1913000000000000e+04,1.2622000000000000e+04,1.3331000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6881000000000000e+04,1.7591000000000000e+04,1.8301000000000000e+04,1.9012000000000000e+04,1.9720000000000000e+04,2.0432000000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266000000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6799000000000000e+04,2.7503000000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610000000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3099000000000000e+04,3.3792000000000000e+04,3.4484000000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {-3.2946263385876073e-01,2.6822672303060707e-01,-2.7219800277644979e-01,3.2114706103684659e-01,-1.1264051193844726e-01,2.1650365243094197e-01,-2.9850534257863964e-01,2.4690262924579376e-01,-3.0264558267838221e-01,1.9002513807042659e-01,-2.2269004121580999e-01,1.9360526493221386e-01,-2.4333024293404595e-01,2.3253426572925068e-01,2.5156939346654091e-02,2.3240995046557339e-01,-2.2672903386601889e-01,1.5590477088799856e-01,-1.5002686187069883e-01,2.0344831295675106e-01,-1.5000864041927442e-01,1.8004430049333014e-01,-1.8236695292080785e-01,1.8325510525277885e-01,3.3572343456822654e-02,1.6768958115164090e-01,-1.7656399543377982e-01,1.9586089774158649e-01,-1.7984311406510889e-01,1.9926780777821917e-01,-2.0358163540196328e-01,1.8788400881417389e-01,-2.6839931133109096e-01,2.4275915958519964e-01,-1.9419370826317078e-01,2.3213640634391663e-01,-2.0322722705876156e-01,2.5395023204178102e-01,-3.1352589198440872e-01,2.8813130768645712e-01,-3.2571760506100766e-01,3.7344440543148194e-01,-3.2440667961683478e-01,4.4966322933102876e-01,-3.5284854392228138e-01,4.5498566236612847e-01,-4.6890882370639664e-01,5.3253439420167337e-01,-5.1690187379933494e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
        double posy_arr[] ={6.9100000000000000e+02,1.3830000000000000e+03,2.0770000000000000e+03,2.7740000000000000e+03,3.4575000000000000e+03,4.1680000000000000e+03,4.8660000000000000e+03,5.5670000000000000e+03,6.2710000000000000e+03,6.9730000000000000e+03,7.4430000000000000e+03,8.4860000000000000e+03,9.1100000000000000e+03,9.7920000000000000e+03,1.0498000000000000e+04,1.1207000000000000e+04,1.1914000000000000e+04,1.2622000000000000e+04,1.3329000000000000e+04,1.4041000000000000e+04,1.4750000000000000e+04,1.5460000000000000e+04,1.6170000000000000e+04,1.6880000000000000e+04,1.7590000000000000e+04,1.8301000000000000e+04,1.9011000000000000e+04,1.9720000000000000e+04,2.0430000000000000e+04,2.1141000000000000e+04,2.1850000000000000e+04,2.2558000000000000e+04,2.3267000000000000e+04,2.3974000000000000e+04,2.4681000000000000e+04,2.5389000000000000e+04,2.6094000000000000e+04,2.6797000000000000e+04,2.7501000000000000e+04,2.8238000000000000e+04,2.8896000000000000e+04,2.9710000000000000e+04,3.0106000000000000e+04,3.1007000000000000e+04,3.1552000000000000e+04,3.2402000000000000e+04,3.3097000000000000e+04,3.3792000000000000e+04,3.4483000000000000e+04};
        arr_to_vec(posy_arr, sizeof(posy_arr)/sizeof(double), posy);
        
        double ccdy_arr[] = {-1.9855267108725011e-01,1.7955082108595999e-01,-1.8827745225040018e-01,1.3932648815497944e-01,-6.0352542704901455e-02,8.3598970550751980e-02,-8.1175104051077959e-02,6.1423375459795058e-02,-4.5004799966324879e-02,5.1255915991506043e-02,1.5851812214634477e-02,1.5587369184767868e-02,1.2194157289131528e-02,-3.3985901939564599e-02,7.0922061628214295e-02,-5.3223665244117681e-02,3.8875501918710656e-02,-5.5471377905873670e-02,5.3105759125309210e-02,-9.9237321842864795e-02,6.2515982392321895e-02,-8.4411396949582967e-02,8.7660527700112317e-02,-9.7615657244219792e-02,1.1887807394615302e-01,-1.0116151698982925e-01,9.2884382992062239e-02,-9.0252420387025509e-02,8.8929836687679620e-02,-1.0833431823799911e-01,8.0427361987862905e-02,-8.8225813952202234e-02,6.7822547934654032e-02,-8.6349198150212400e-02,8.7246760279810182e-02,-7.0883233135712959e-02,4.1376134151766455e-02,-3.5761138416796644e-02,3.7183085174551947e-02,-1.8063316353517003e-02,2.0949603842599852e-02,-2.4268409874204040e-02,-2.2141072979198307e-02,3.0889019160442014e-02,3.4287549363534349e-02,7.0188151962212772e-02,-6.9597035784645517e-02,9.1561840117775795e-02,-1.4346661758051732e-01};
        arr_to_vec(ccdy_arr, sizeof(ccdy_arr)/sizeof(double), ccdy);
        
      }else if (tdi == 56){
        
        double posx_arr[] = {6.9050000000000000e+02,1.3830000000000000e+03,2.0775000000000000e+03,2.7725000000000000e+03,3.4635000000000000e+03,4.1680000000000000e+03,4.8670000000000000e+03,5.5680000000000000e+03,6.2695000000000000e+03,6.9720000000000000e+03,7.6765000000000000e+03,8.3800000000000000e+03,9.0845000000000000e+03,9.7915000000000000e+03,1.0502500000000000e+04,1.1205500000000000e+04,1.1913500000000000e+04,1.2621500000000000e+04,1.3330500000000000e+04,1.4040500000000000e+04,1.4749500000000000e+04,1.5460000000000000e+04,1.6169500000000000e+04,1.6880500000000000e+04,1.7590500000000000e+04,1.8301000000000000e+04,1.9011500000000000e+04,1.9720500000000000e+04,2.0431500000000000e+04,2.1140000000000000e+04,2.1849000000000000e+04,2.2558000000000000e+04,2.3266500000000000e+04,2.3974000000000000e+04,2.4682000000000000e+04,2.5388000000000000e+04,2.6094000000000000e+04,2.6798500000000000e+04,2.7502500000000000e+04,2.8207000000000000e+04,2.8910000000000000e+04,2.9610500000000000e+04,3.0310000000000000e+04,3.1009000000000000e+04,3.1707000000000000e+04,3.2402000000000000e+04,3.3098000000000000e+04,3.3792000000000000e+04,3.4483500000000000e+04};
        arr_to_vec(posx_arr, sizeof(posx_arr)/sizeof(double), posx);
        
        double ccdx_arr[] = {-3.5011442399307202e-01,3.1186407063727184e-01,-3.2335982284254117e-01,3.5688803627847732e-01,-1.5016902336398030e-01,2.7091922018898873e-01,-3.4524579685389989e-01,3.1697476178278094e-01,-3.3427642010528191e-01,2.4348731667372364e-01,-2.5459010039954394e-01,2.2227864965341840e-01,-2.4963564133255550e-01,2.6519143229617087e-01,-1.2640033051156893e-02,2.6926418565530419e-01,-2.6413094069459742e-01,1.7933663392775823e-01,-1.7857720325097262e-01,2.3227298026241555e-01,-1.8833606658120045e-01,2.0690430915056696e-01,-2.2153185513515222e-01,2.2470157361209891e-01,-1.0775858639518222e-02,1.9409607914016191e-01,-1.9017563481638641e-01,2.0941570156418010e-01,-1.9959115270537459e-01,2.3450585103367219e-01,-2.4346167898401047e-01,2.3507302665020746e-01,-2.9839629178583321e-01,2.8796840809065738e-01,-2.2339992370188613e-01,2.6676508093280049e-01,-2.2822730588765003e-01,2.7316283112057416e-01,-3.4718648441520028e-01,3.2886139038062245e-01,-3.1213617802392812e-01,4.1015850839081253e-01,-3.6843147363566531e-01,4.4417245109948189e-01,-3.4664171603617239e-01,4.8513123485069182e-01,-4.9177442050887177e-01,5.5564212715312777e-01,-5.1330089584066618e-01};
        arr_to_vec(ccdx_arr, sizeof(ccdx_arr)/sizeof(double), ccdx);
        
{'fraction_non_alphanumeric': 0.13490115001938235, 'fraction_numerical': 0.605024643272479, 'mean_word_length': 7.431750972762646, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 876, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1047866', 'n_tokens_mistral': 44261, 'n_tokens_neox': 23859, 'n_words': 1293}