SampleReader.C 5.86 KB
Newer Older
Francois Gygi committed
1 2
////////////////////////////////////////////////////////////////////////////////
//
3
// Copyright (c) 2008-2012 The Regents of the University of California
Francois Gygi committed
4 5 6
//
// This file is part of Qbox
//
Francois Gygi committed
7 8
// Qbox is distributed under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 2 of
Francois Gygi committed
9 10 11 12 13 14
// the License, or (at your option) any later version.
// See the file COPYING in the root directory of this distribution
// or <http://www.gnu.org/licenses/>.
//
////////////////////////////////////////////////////////////////////////////////
//
Francois Gygi committed
15 16 17 18 19 20 21 22 23 24 25 26 27
// SampleReader.C:
//
////////////////////////////////////////////////////////////////////////////////

#include "Sample.h"
#include "SampleReader.h"

#include "XMLGFPreprocessor.h"

#include "Timer.h"

#include <cassert>
#include <string>
28
#include <cstring> // memcpy
Francois Gygi committed
29
#include <iostream>
Francois Gygi committed
30
#include <fstream>
Francois Gygi committed
31 32
#include <sys/stat.h>

Francois Gygi committed
33 34
#include "SampleHandler.h"
#include "StructuredDocumentHandler.h"
Francois Gygi committed
35 36 37 38 39 40 41 42
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/framework/LocalFileInputSource.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
using namespace xercesc;
43
using namespace std;
Francois Gygi committed
44 45 46 47 48 49 50

////////////////////////////////////////////////////////////////////////////////
SampleReader::SampleReader(const Context& ctxt) : ctxt_(ctxt) {}

////////////////////////////////////////////////////////////////////////////////
void SampleReader::readSample (Sample& s, const string uri, bool serial)
{
51 52
  Timer tm;
  tm.start();
53 54 55 56 57 58 59 60
  const bool onpe0 = ctxt_.onpe0();

  SAX2XMLReader::ValSchemes valScheme;
  valScheme = SAX2XMLReader::Val_Auto;
  //alternate choices of validation schemes
  //valScheme = SAX2XMLReader::Val_Always;
  //valScheme = SAX2XMLReader::Val_Never;

Francois Gygi committed
61
  bool doNamespaces = true;
62 63 64
  // Validate agains schema on pe0 only to avoid multiple warning messages
  // This does not weaken validation since all tasks parse the same document
  bool doSchema = onpe0;
Francois Gygi committed
65 66 67 68
  bool schemaFullChecking = true;
  bool namespacePrefixes = false;
  SAX2XMLReader* parser = 0;
  MemBufInputSource* memBufIS = 0;
69

70 71
  // XMLPlatformUtils initialization on all tasks
  try
Francois Gygi committed
72
  {
73
    XMLPlatformUtils::Initialize();
Francois Gygi committed
74
  }
75 76

  catch (const XMLException& toCatch)
Francois Gygi committed
77
  {
78
    cout << "  SampleReader::readSample: Error during XML initialization :\n"
79
         << StrX(toCatch.getMessage()) << endl;
80
    return;
Francois Gygi committed
81
  }
82

Francois Gygi committed
83 84
  string xmlcontent;
  DoubleMatrix gfdata(ctxt_);
85

86
  XMLGFPreprocessor xmlgfp;
87 88 89 90 91
  if ( xmlgfp.process(uri.c_str(),gfdata,xmlcontent,serial) )
  {
    cout << "  SampleReader::readSample: Error in XMLGFPreprocessor" << endl;
    return;
  }
92

93 94
  // Each task holds a copy of xmlcontent
  // The distributed matrix gfdata contains the grid function data
95

96 97 98
  if ( onpe0 )
  {
    cout << " xmlcontent.size(): " << xmlcontent.size() << endl;
Francois Gygi committed
99
#if DEBUG
100
    cout << ctxt_.mype() << ": xmlcontent: " << xmlcontent << endl;
Francois Gygi committed
101
#endif
Francois Gygi committed
102
  }
103 104
  memBufIS = new MemBufInputSource
    ( (const XMLByte*) &xmlcontent[0], xmlcontent.size(), "buf_id", false);
105

106 107 108
  // parse xmlcontent on each task
  parser = XMLReaderFactory::createXMLReader();
  if (valScheme == SAX2XMLReader::Val_Auto)
Francois Gygi committed
109
  {
110 111 112
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgXercesDynamic, true);
  }
113

114
  if (valScheme == SAX2XMLReader::Val_Never)
Francois Gygi committed
115
  {
116 117
    parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
  }
Francois Gygi committed
118

119
  if (valScheme == SAX2XMLReader::Val_Always)
Francois Gygi committed
120
  {
121 122 123
    parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    parser->setFeature(XMLUni::fgXercesDynamic, false);
  }
124

125 126 127 128
  parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
  parser->setFeature(XMLUni::fgXercesSchema, doSchema);
  parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
  parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, namespacePrefixes);
129

130
  SampleHandler* s_handler = new SampleHandler(s,gfdata);
131

132 133 134 135 136 137 138 139 140 141
  try
  {
    StructuredDocumentHandler handler(s_handler);
    parser->setContentHandler(&handler);
    parser->setErrorHandler(&handler);

    ctxt_.barrier();
    if ( onpe0 ) cout << " Starting XML parsing" << endl;
      parser->parse(*memBufIS);
    if ( onpe0 ) cout << " XML parsing done" << endl;
Francois Gygi committed
142
    // errorCount = parser->getErrorCount();
143
  }
144

145 146 147 148 149 150
  catch (const XMLException& toCatch)
  {
    cout << "\nAn error occurred\n  Error: "
         << StrX(toCatch.getMessage())
         << "\n" << endl;
  }
Francois Gygi committed
151

152 153 154 155 156 157 158 159
  catch (const SAXParseException& e)
  {
    cout << "\na SAXParseException occurred in file "
         << StrX(e.getSystemId())
         << ", line " << e.getLineNumber()
         << ", char " << e.getColumnNumber()
         << "\n  Message: " << StrX(e.getMessage()) << endl;
  }
Francois Gygi committed
160

161 162 163 164
  delete s_handler;
  delete parser;
  delete memBufIS;
  XMLPlatformUtils::Terminate();
Francois Gygi committed
165

166 167 168
  tm.stop();
  if ( onpe0 )
    cout << " SampleReader: read time: " << tm.real() << " s" << endl;
169

170
  // force consistency of unit cell
171
  // Avoid inconsistency between atomset unit cell and wavefunction unit cell
172
  // copy wavefunction domain on atomset unit_cell
173 174 175
  //
  // If the wave function cell was set:
  if ( s.wf.cell().volume() != 0.0 )
176
  {
Francois Gygi committed
177
    // cout << "copying wf.cell on atoms.cell" << endl;
178 179 180
    s.atoms.set_cell(s.wf.cell());
  }

181 182 183 184 185
  // If only the atomset was read (no wave function) initialize the
  // wave function with appropriate sizes
  // Use the Wavefunction cell volume as a criterion to determine if
  // the Wavefunction was read
  if ( s.wf.cell().volume() == 0.0 )
186
  {
187
    // the Wavefunction was not read
188 189 190 191 192 193 194
    s.wf.reset();
    // set wf cell
    s.wf.resize(s.atoms.cell(),s.atoms.cell(),s.wf.ecut());
    // set number of states from charge in atomset
    s.wf.set_nel(s.atoms.nel());
    s.wf.update_occ(0.0);

195 196 197 198 199 200
    // if a wavefunction_velocity was read, delete it
    if ( s.wfv != 0 )
    {
      delete s.wfv;
      s.wfv = 0;
    }
Francois Gygi committed
201
  }
Francois Gygi committed
202
}