private void readFrequencies() throws Exception, IOException {
    String[] tokens; String[] symmetries; String[] frequencies;
    String[] red_masses; String[] frc_consts; String[] intensities;
    
    while (readLine() != null &&
        line.indexOf(":")<0) {
    }
    if (line == null)
      throw (new Exception("No frequencies encountered"));
    
    // G98 ends the frequencies with a line with a space (03 an empty line)
    // so I decided to read till the line is too short
    while ((line= readLine()) != null &&
        line.length() > 15)
    {
      // we now have the line with the vibration numbers in them, but don't need it
      symmetries = getTokens(readLine()); // read symmetry labels
      // TODO I should really read all the properties of the vibrations listed
      // and not limit myself to only IR type ones..
      frequencies = getTokens(discardLinesUntilStartsWith(" Frequencies"), 15);
      red_masses = getTokens(discardLinesUntilStartsWith(" Red. masses"), 15);
      frc_consts = getTokens(discardLinesUntilStartsWith(" Frc consts"), 15);
      intensities = getTokens(discardLinesUntilStartsWith(" IR Inten"), 15);
      int frequencyCount = frequencies.length;
      
      for (int i = 0; i < frequencyCount; ++i) {
        atomSetCollection.cloneLastAtomSet();
        atomSetCollection.setAtomSetName(
            symmetries[i] + " "
            + frequencies[i]+" cm**-1"
//            + ", Inten = " + intensities[i] + " KM/Mole "
//            + energyKey + " = " + energyString
        );
        // set the properties
        atomSetCollection.setAtomSetProperty(energyKey, energyString);
        atomSetCollection.setAtomSetProperty("Frequency",
            frequencies[i]+" cm**-1");
        atomSetCollection.setAtomSetProperty("Reduced Mass",
            red_masses[i]+" AMU");
        atomSetCollection.setAtomSetProperty("Force Constant",
            frc_consts[i]+" mDyne/A");
        atomSetCollection.setAtomSetProperty("IR Intensity",
            intensities[i]+" KM/Mole");
        atomSetCollection.setAtomSetProperty(SmarterJmolAdapter.PATH_KEY,
            "Calculation " + calculationNumber+
            SmarterJmolAdapter.PATH_SEPARATOR+"Frequencies");
      }
      
      int atomCount = atomSetCollection.getLastAtomSetAtomCount();
      int firstModelAtom =
        atomSetCollection.atomCount - frequencyCount * atomCount;
      
      // position to start reading the displacement vectors
      discardLinesUntilStartsWith(" Atom AN");
      
      // read the displacement vectors for every atom and frequency
      float x, y, z;
      for (int i = 0; i < atomCount; ++i) {
        tokens = getTokens(readLine());
        int atomCenterNumber = parseInt(tokens[0]);
        for (int j = 0, offset=FREQ_FIRST_VECTOR_OFFSET;
        j < frequencyCount; ++j) {
          int atomOffset = firstModelAtom+j*atomCount + atomCenterNumber - 1 ;
          Atom atom = atomSetCollection.atoms[atomOffset];
          x = parseFloat(tokens[offset++]);
          y = parseFloat(tokens[offset++]);
          z = parseFloat(tokens[offset++]);
          atom.addVibrationVector(x, y, z);
        }
      }
    }
  }