public Viterbi(String tagset, String gtagset, String datafile) 
    	throws FileNotFoundException, WrongFormatException, POSNotFoundException
    {

	POS.loadFromFile (tagset, gtagset);

	Scanner sc = null;
	// deals with the actual data file
	try 
	{
	    // tries to open the file
	    sc = new Scanner(new BufferedReader(new FileReader(datafile)));

	    // reads in the first two numerical values
	    this.numPOS = sc.nextInt();
	    sc.nextLine();
	    this.numWords = sc.nextInt();
	    sc.nextLine();

	    // basic check that the number of parts of speech matches up
	    if (this.numPOS != POS.numPOS())
			throw new WrongFormatException("The training file does not seem to match the indicated tagset.");

	    // initializes the probability array
	    this.p_transmission = new float[this.numPOS][this.numPOS];
	    
	    // reads file and loads emission probabilities
	    String word;
	    float[] probability;
	    String[] line;
	    int numEntries;
	    
	    for (int i = 0; i < numWords; i++)
	    {
		probability = new float[this.numPOS];
		word = sc.next("\\S+");
		sc.skip(" ");
		line = sc.nextLine().split(" ");
		numEntries = (line.length+1)/2;

		// sets default probabilities
		for (int j = 0; j < numPOS; j++)
		{
		    probability[j] = Float.NEGATIVE_INFINITY;
		}
		
		// gets actual probabilities
		for (int j = 0; j < numEntries; j+=2)
		{
		    probability[Integer.parseInt(line[j])] = Float.parseFloat(line[j+1]);
		}

		// adds to hash map
		this.p_emission.put(word, probability);
	    }
	    
	    // reads file and loads transmission probabilities
	    for (int i = 0; i < numPOS; i++)
	    {
		// gets POS and checks that it has the right index
		word = sc.next("\\S+");
		sc.skip(" ");
		if (i != POS.getIndexBySymbol(word))
		    throw new WrongFormatException("The training file does not seem to match the indicated tagset.");

		line = sc.nextLine().split(" ");
		numEntries = (line.length+1)/2;

		// sets default probabilities
		for (int j = 0; j < numPOS; j++)
		{
		    p_transmission[i][j] = Float.NEGATIVE_INFINITY;
		}
		
		// gets actual probabilities
		for (int j = 0; j < numEntries; j+=2)
		{
		    p_transmission[i][Integer.parseInt(line[j])] = Float.parseFloat(line[j+1]);
		}
	    }
	}
	finally
	{
	    if (sc != null)
			sc.close();
	}
    }