Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/analyzer.cpp

    • Property mode changed from 100644 to 100755
    r6ce722 r97c751  
    2525  periodentafel *periode = NULL; // and a period table of all elements
    2626  EnergyMatrix Energy;
    27   EnergyMatrix EnergyFragments;
     27  EnergyMatrix Hcorrection;
    2828  ForceMatrix Force;
    29   ForceMatrix ForceFragments;
    30   HessianMatrix Hessian;
    31   HessianMatrix HessianFragments;
    32   EnergyMatrix Hcorrection;
    33   EnergyMatrix HcorrectionFragments;
    3429  ForceMatrix Shielding;
    3530  ForceMatrix ShieldingPAS;
     31  ForceMatrix Chi;
     32  ForceMatrix ChiPAS;
    3633  EnergyMatrix Time;
     34  EnergyMatrix EnergyFragments;
     35  EnergyMatrix HcorrectionFragments;
     36  ForceMatrix ForceFragments;
    3737  ForceMatrix ShieldingFragments;
    3838  ForceMatrix ShieldingPASFragments;
     39  ForceMatrix ChiFragments;
     40  ForceMatrix ChiPASFragments;
    3941  KeySetsContainer KeySet;
    4042  ofstream output;
     
    5153  stringstream yrange;
    5254  char *dir = NULL;
    53   bool NoHCorrection = false;
    54   bool NoHessian = false;
    55   bool NoTime = false;
     55  bool Hcorrected = true;
    5656  double norm;
    5757  int counter;
     
    8888  // ------------- Parse through all Fragment subdirs --------
    8989  if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix,0,0)) return 1;
    90   if (!Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0)) {
    91     NoHCorrection = true;
    92     cout << "No HCorrection file found, skipping these." << endl;
    93   }
    94  
     90  Hcorrected = Hcorrection.ParseFragmentMatrix(argv[1], "", HCORRECTIONSUFFIX,0,0);
    9591  if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix,0,0)) return 1;
    96   if (!Hessian.ParseFragmentMatrix(argv[1], dir, HessianSuffix,0,0)) {
    97     NoHessian = true;
    98     cout << "No Hessian file found, skipping these." << endl;
    99   }
    100   if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) {
    101     NoTime = true;
    102     cout << "No speed file found, skipping these." << endl;
    103   }
     92  if (!Time.ParseFragmentMatrix(argv[1], dir, TimeSuffix, 10,1)) return 1;
    10493  if (periode != NULL) { // also look for PAS values
    10594    if (!Shielding.ParseFragmentMatrix(argv[1], dir, ShieldingSuffix, 1, 0)) return 1;
    10695    if (!ShieldingPAS.ParseFragmentMatrix(argv[1], dir, ShieldingPASSuffix, 1, 0)) return 1;
     96    if (!Chi.ParseFragmentMatrix(argv[1], dir, ChiSuffix, 1, 0)) return 1;
     97    if (!ChiPAS.ParseFragmentMatrix(argv[1], dir, ChiPASSuffix, 1, 0)) return 1;
    10798  }
    10899
    109100  // ---------- Parse the TE Factors into an array -----------------
    110   if (!Energy.InitialiseIndices()) return 1;
    111   if (!NoHCorrection)
    112     Hcorrection.InitialiseIndices();
     101  if (!Energy.ParseIndices()) return 1;
     102  if (Hcorrected) Hcorrection.ParseIndices();
    113103 
    114104  // ---------- Parse the Force indices into an array ---------------
    115105  if (!Force.ParseIndices(argv[1])) return 1;
    116106  if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return 1;
    117   if (!ForceFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    118 
    119   // ---------- Parse hessian indices into an array -----------------
    120   if (!NoHessian) {
    121     if (!Hessian.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    122     if (!HessianFragments.AllocateMatrix(Hessian.Header, Hessian.MatrixCounter, Hessian.RowCounter, Hessian.ColumnCounter)) return 1;
    123     if (!HessianFragments.InitialiseIndices((class MatrixContainer *)&Force)) return 1;
    124   }
     107  if (!ForceFragments.ParseIndices(argv[1])) return 1;
    125108
    126109  // ---------- Parse the shielding indices into an array ---------------
     
    132115    if(!ShieldingFragments.ParseIndices(argv[1])) return 1;
    133116    if(!ShieldingPASFragments.ParseIndices(argv[1])) return 1;
     117    if(!Chi.ParseIndices(argv[1])) return 1;
     118    if(!ChiPAS.ParseIndices(argv[1])) return 1;
     119    if (!ChiFragments.AllocateMatrix(Chi.Header, Chi.MatrixCounter, Chi.RowCounter, Chi.ColumnCounter)) return 1;
     120    if (!ChiPASFragments.AllocateMatrix(ChiPAS.Header, ChiPAS.MatrixCounter, ChiPAS.RowCounter, ChiPAS.ColumnCounter)) return 1;
     121    if(!ChiFragments.ParseIndices(argv[1])) return 1;
     122    if(!ChiPASFragments.ParseIndices(argv[1])) return 1;
    134123  }
    135124
     
    140129  // ---------- Parse fragment files created by 'joiner' into an array -------------
    141130  if (!EnergyFragments.ParseFragmentMatrix(argv[1], dir, EnergyFragmentSuffix,0,0)) return 1;
    142   if (!NoHCorrection)
    143     HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
     131  if (Hcorrected) HcorrectionFragments.ParseFragmentMatrix(argv[1], dir, HcorrectionFragmentSuffix,0,0);
    144132  if (!ForceFragments.ParseFragmentMatrix(argv[1], dir, ForceFragmentSuffix,0,0)) return 1;
    145   if (!NoHessian)
    146     if (!HessianFragments.ParseFragmentMatrix(argv[1], dir, HessianFragmentSuffix,0,0)) return 1;
    147133  if (periode != NULL) { // also look for PAS values
    148134    if (!ShieldingFragments.ParseFragmentMatrix(argv[1], dir, ShieldingFragmentSuffix, 1, 0)) return 1;
    149135    if (!ShieldingPASFragments.ParseFragmentMatrix(argv[1], dir, ShieldingPASFragmentSuffix, 1, 0)) return 1;
     136    if (!ChiFragments.ParseFragmentMatrix(argv[1], dir, ChiFragmentSuffix, 1, 0)) return 1;
     137    if (!ChiPASFragments.ParseFragmentMatrix(argv[1], dir, ChiPASFragmentSuffix, 1, 0)) return 1;
    150138  }
    151139
     
    156144  filename << argv[3] << "/" << "energy-forces.all";
    157145  output.open(filename.str().c_str(), ios::out);
    158   output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header[Energy.MatrixCounter] << endl;
     146  output << endl << "Total Energy" << endl << "==============" << endl << Energy.Header << endl;
    159147  for(int j=0;j<Energy.RowCounter[Energy.MatrixCounter];j++) {
    160     for(int k=0;k<Energy.ColumnCounter[Energy.MatrixCounter];k++)
     148    for(int k=0;k<Energy.ColumnCounter;k++)
    161149      output << scientific << Energy.Matrix[ Energy.MatrixCounter ][j][k] << "\t";
    162150    output << endl;
     
    164152  output << endl;
    165153 
    166   output << endl << "Total Forces" << endl << "===============" << endl << Force.Header[Force.MatrixCounter] << endl;
     154  output << endl << "Total Forces" << endl << "===============" << endl << Force.Header << endl;
    167155  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    168     for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
     156    for(int k=0;k<Force.ColumnCounter;k++)
    169157      output << scientific << Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    170158    output << endl;
     
    172160  output << endl;
    173161
    174   if (!NoHessian) {
    175     output << endl << "Total Hessian" << endl << "===============" << endl << Hessian.Header[Hessian.MatrixCounter] << endl;
    176     for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
    177       for(int k=0;k<Hessian.ColumnCounter[Hessian.MatrixCounter];k++)
    178         output << scientific << Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
    179       output << endl;
    180     }
    181     output << endl;
    182   }
    183 
    184   if (periode != NULL) { // also look for PAS values
    185     output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header[Hessian.MatrixCounter] << endl;
     162  if (periode != NULL) { // also look for PAS values
     163    output << endl << "Total Shieldings" << endl << "===============" << endl << Shielding.Header << endl;
    186164    for(int j=0;j<Shielding.RowCounter[Shielding.MatrixCounter];j++) {
    187       for(int k=0;k<Shielding.ColumnCounter[Shielding.MatrixCounter];k++)
     165      for(int k=0;k<Shielding.ColumnCounter;k++)
    188166        output << scientific << Shielding.Matrix[ Shielding.MatrixCounter ][j][k] << "\t";
    189167      output << endl;
     
    191169    output << endl;
    192170 
    193     output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header[ShieldingPAS.MatrixCounter] << endl;
     171    output << endl << "Total Shieldings PAS" << endl << "===============" << endl << ShieldingPAS.Header << endl;
    194172    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    195       for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
     173      for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    196174        output << scientific << ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t";
    197175      output << endl;
    198176    }
    199177    output << endl;
    200   }
    201  
    202   if (!NoTime) {
    203     output << endl << "Total Times" << endl << "===============" << endl << Time.Header[Time.MatrixCounter] << endl;
    204     for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
    205       for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
    206         output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
    207       }
    208       output << endl;
    209     }
    210     output << endl;
    211   }
     178
     179    output << endl << "Total Chis" << endl << "===============" << endl << Chi.Header[Chi.MatrixCounter] << endl;
     180    for(int j=0;j<Chi.RowCounter[Chi.MatrixCounter];j++) {
     181      for(int k=0;k<Chi.ColumnCounter;k++)
     182        output << scientific << Chi.Matrix[ Chi.MatrixCounter ][j][k] << "\t";
     183      output << endl;
     184    }
     185    output << endl;
     186 
     187    output << endl << "Total Chis PAS" << endl << "===============" << endl << ChiPAS.Header[ChiPAS.MatrixCounter] << endl;
     188    for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
     189      for(int k=0;k<ChiPAS.ColumnCounter;k++)
     190        output << scientific << ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t";
     191      output << endl;
     192    }
     193    output << endl;
     194  }
     195 
     196  output << endl << "Total Times" << endl << "===============" << endl << Time.Header << endl;
     197  for(int j=0;j<Time.RowCounter[Time.MatrixCounter];j++) {
     198    for(int k=0;k<Time.ColumnCounter;k++) {
     199      output << scientific << Time.Matrix[ Time.MatrixCounter ][j][k] << "\t";
     200    }
     201    output << endl;
     202  }
     203  output << endl;
    212204  output.close();
    213   if (!NoTime)
    214     for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++)
    215       Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
     205  for(int k=0;k<Time.ColumnCounter;k++)
     206    Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k] = Time.Matrix[ Time.MatrixCounter ][Time.RowCounter[Time.MatrixCounter]-1][k];
    216207
    217208  // +++++++++++++++ ANALYZING ++++++++++++++++++++++++++++++
     
    223214  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    224215  // +++++++++++++++++++++++++++++++++++++++ Plotting Delta Simtime vs Bond Order
    225   if (!NoTime) {
    226     if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
    227     if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
    228     for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    229       for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
    230         Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
    231       }
    232     counter = 0;
    233     output << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
    234     output2 << "#Order\tFrag.No.\t" << Time.Header[Time.MatrixCounter] << endl;
    235     for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
    236       for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
    237         for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
    238           for(int k=Time.ColumnCounter[Time.MatrixCounter];k--;) {
    239             Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
    240           }
    241       counter += KeySet.FragmentsPerOrder[BondOrder];
    242       output << BondOrder+1 << "\t" << counter;
    243       output2 << BondOrder+1 << "\t" << counter;
    244       for(int k=0;k<Time.ColumnCounter[Time.MatrixCounter];k++) {
    245         output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    246         if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
    247           output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
    248         else
    249           output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
    250       }
    251       output << endl;
    252       output2 << endl;
    253     }
    254     output.close();
    255     output2.close();
    256   }
    257 
    258   if (!NoHessian) {
    259     // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in hessian to full QM
    260     if (!CreateDataDeltaHessianOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaHessian_xx-Order", "Plot of error between approximated hessian and full hessian versus the Bond Order", datum)) return 1;
    261 
    262     if (!CreateDataDeltaFrobeniusOrderPerAtom(Hessian, HessianFragments, KeySet, argv[3], "DeltaFrobeniusHessian_xx-Order", "Plot of error between approximated hessian and full hessian in the frobenius norm versus the Bond Order", datum)) return 1;
    263 
    264     // ++++++++++++++++++++++++++++++++++++++Plotting Hessian vs. Order
    265     if (!CreateDataHessianOrderPerAtom(HessianFragments, KeySet, argv[3], "Hessian_xx-Order", "Plot of approximated hessian versus the Bond Order", datum)) return 1;
    266     if (!AppendOutputFile(output, argv[3], "Hessian_xx-Order.dat" )) return false;
    267     output << endl << "# Full" << endl;
    268     for(int j=0;j<Hessian.RowCounter[Hessian.MatrixCounter];j++) {
    269       output << j << "\t";
    270       for(int k=0;k<Hessian.ColumnCounter[Force.MatrixCounter];k++)
    271         output << scientific <<  Hessian.Matrix[ Hessian.MatrixCounter ][j][k] << "\t";
    272       output << endl;
    273     }
    274     output.close();
    275   }
     216  if (!OpenOutputFile(output, argv[3], "SimTime-Order.dat" )) return false;
     217  if (!OpenOutputFile(output2, argv[3], "DeltaSimTime-Order.dat" )) return false;
     218  for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     219    for(int k=Time.ColumnCounter;k--;) {
     220      Time.Matrix[ Time.MatrixCounter ][j][k] = 0.;
     221    }
     222  counter = 0;
     223  output << "#Order\tFrag.No.\t" << Time.Header << endl;
     224  output2 << "#Order\tFrag.No.\t" << Time.Header << endl;
     225  for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     226    for(int i=KeySet.FragmentsPerOrder[BondOrder];i--;)
     227      for(int j=Time.RowCounter[Time.MatrixCounter];j--;)
     228        for(int k=Time.ColumnCounter;k--;) {
     229          Time.Matrix[ Time.MatrixCounter ][j][k] += Time.Matrix[ KeySet.OrderSet[BondOrder][i] ][j][k];
     230        }
     231    counter += KeySet.FragmentsPerOrder[BondOrder];
     232    output << BondOrder+1 << "\t" << counter;
     233    output2 << BondOrder+1 << "\t" << counter;
     234    for(int k=0;k<Time.ColumnCounter;k++) {
     235      output << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     236      if (fabs(Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k]) > MYEPSILON)
     237        output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k] / Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter] ][k];
     238      else
     239        output2 << "\t" << scientific << Time.Matrix[ Time.MatrixCounter ][ Time.RowCounter[Time.MatrixCounter]-1 ][k];
     240    }
     241    output << endl;
     242    output2 << endl;
     243  }
     244  output.close();
     245  output2.close();
    276246
    277247  // +++++++++++++++++++++++++++++++++++++++ Plotting shieldings
     
    284254    for(int j=0;j<ShieldingPAS.RowCounter[ShieldingPAS.MatrixCounter];j++) {
    285255      output << j << "\t";
    286       for(int k=0;k<ShieldingPAS.ColumnCounter[ShieldingPAS.MatrixCounter];k++)
     256      for(int k=0;k<ShieldingPAS.ColumnCounter;k++)
    287257        output << scientific <<  ShieldingPAS.Matrix[ ShieldingPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
    288258      output << endl;
    289259    }
    290   }
    291   output.close();
     260    output.close();
     261    if (!CreateDataDeltaForcesOrderPerAtom(ChiPAS, ChiPASFragments, KeySet, argv[3], "DeltaChisPAS-Order", "Plot of error between approximated Chis and full Chis versus the Bond Order", datum)) return 1;
     262    if (!CreateDataForcesOrderPerAtom(ChiPASFragments, KeySet, argv[3], "ChisPAS-Order", "Plot of approximated Chis versus the Bond Order", datum)) return 1;
     263    if (!AppendOutputFile(output, argv[3], "ChisPAS-Order.dat" )) return false;
     264    output << endl << "# Full" << endl;
     265    for(int j=0;j<ChiPAS.RowCounter[ChiPAS.MatrixCounter];j++) {
     266      output << j << "\t";
     267      for(int k=0;k<ChiPAS.ColumnCounter;k++)
     268        output << scientific <<  ChiPAS.Matrix[ ChiPAS.MatrixCounter ][j][k] << "\t"; //*(((k>1) && (k<6))? 1.e6 : 1.) << "\t";
     269      output << endl;
     270    }
     271    output.close();
     272  }
    292273
    293274 
     
    316297  for(int j=0;j<Force.RowCounter[Force.MatrixCounter];j++) {
    317298    output << j << "\t";
    318     for(int k=0;k<Force.ColumnCounter[Force.MatrixCounter];k++)
     299    for(int k=0;k<Force.ColumnCounter;k++)
    319300      output << scientific <<  Force.Matrix[ Force.MatrixCounter ][j][k] << "\t";
    320301    output << endl;
     
    365346  yrange.str("[1e-8:1e+1]");
    366347 
    367   if (!NoTime) {
    368     // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
    369     if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "",  1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
    370   }
     348  // +++++++++++++++++++++++++++++++++++++++ Plotting Simtime vs Bond Order
     349  if (!CreatePlotOrder(Time, KeySet, argv[3], "SimTime-Order", 1, "below", "y", "",  1, 1, "bond order k", "Evaluation time [s]", Orderxrange.str().c_str(), "", "1" , "with linespoints", EnergyPlotLine)) return 1;
    371350 
    372351  // +++++++++++++++++++++++++++++++++++++++ Plotting deviation in energy to full QM
     
    466445    }
    467446    output << "'ShieldingsPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
     447    output.close(); 
     448    output2.close(); 
     449
     450    if(!OpenOutputFile(output, argv[3], "ChisPAS-Order.pyx")) return 1;
     451    if(!OpenOutputFile(output2, argv[3], "DeltaChisPAS-Order.pyx")) return 1;
     452    CreatePlotHeader(output, "ChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     453    CreatePlotHeader(output2, "DeltaChisPAS-Order", 1, "top right", NULL, NULL,  1, 5, "nuclei index", "iso chemical Chi value [ppm]");
     454    output << "set boxwidth " << step << endl;
     455    output << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     456    output2 << "plot [0:" << ChiPAS.RowCounter[ChiPAS.MatrixCounter]+10 << "]\\" << endl;
     457    for (int BondOrder=0;BondOrder<KeySet.Order;BondOrder++) {
     458      output << "'ChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1+" << step*(double)BondOrder << "):7 with boxes, \\" << endl;
     459      output2 << "'DeltaChisPAS-Order.dat' index " << BondOrder << " title 'Order " << BondOrder+1 << "' using ($1):7 with linespoints";
     460      if (BondOrder-1 != KeySet.Order)
     461        output2 << ", \\" << endl;
     462    }
     463    output << "'ChisPAS-Order.dat' index " << KeySet.Order << " title 'Full' using ($1+" << step*(double)KeySet.Order << "):7 with boxes" << endl;
    468464    output.close(); 
    469465    output2.close(); 
Note: See TracChangeset for help on using the changeset viewer.