Ejemplo n.º 1
0
///////////////////////////////////////////////////////////////////////////////
// Run calculations.
///////////////////////////////////////////////////////////////////////////////
void efn2Interface::run() {

	// Create a variable that handles errors.
	int error = 0;

	/*
	 * Use the constructor for RNA that specifies a filename.
	 * Specify type = 1 (CT file).
	 * isRNA identifies whether the strand is RNA (true) or DNA (false).
	 *
	 * After construction of the strand data structure, create the error checker which monitors for errors.  
	 * Throughout, the error status of the calculation is checked with a variant of the isErrorStatus method, which returns 0 if no error occurred.
	 * The calculation proceeds as long as error = 0.
	 */
	cout << "Initializing nucleic acids..." << flush;
	RNA* strand = new RNA( ctFile.c_str(), 1, isRNA );
	ErrorChecker<RNA>* checker = new ErrorChecker<RNA>( strand );
	error = checker->isErrorStatus();
	if( error == 0 ) { cout << "done." << endl; }

	/*
	 * Check the strand for pseudoknots by looking through each structure with the ContainsPseudoknot method.
	 * efn2 cannot handle pseudoknots, so if the strand contains pseudoknots, this is considered an error.
	 */
	if( error == 0 ) {
		structures = strand->GetStructureNumber();
		for( int i = 1; i <= structures; i++ ) {
			if( strand->ContainsPseudoknot( i ) ) {
				cerr << "Nucleic acids contain pseudoknots; cannot proceed." << endl;
				error = -1;
			}
		}
	}

	/*
	 * Set the temperature using the SetTemperature method.
	 * Only set the temperature if a given temperature doesn't equal the default.
	 * If the temperature does need to be set, use the error checker's isErrorStatus method to check for errors.
	 */
	if( ( error == 0 ) && ( temperature != 310.15 ) ) {

		// Show a message saying that the temperature is being set.
		cout << "Setting temperature..." << flush;

		// Set the temperature and check for errors.
		int tempError = strand->SetTemperature( temperature );
		error = checker->isErrorStatus( tempError );

		// If no error occurred, print a message saying that temperature is set.
		if( error == 0 ) { cout << "done." << endl; }
	}

	/*
	 * Read SHAPE constraints, if applicable.
	 * When reading SHAPE constraints, use the ReadSHAPE method.
	 * After constraints are read, use the error checker's isErrorStatus method to check for errors.
	 */
	if( error == 0 && SHAPEFile != "" ) {

		// Show a message saying that SHAPE constraints are being read.
		cout << "Applying SHAPE constraints..." << flush;

		// Initialize the single stranded SHAPE slope and intercept.
		// For now, these are hard-coded as 0.
		double slopeSingle = 0;
		double interceptSingle = 0;

		// Read SHAPE constraints and check for errors.
		int constraintError = strand->ReadSHAPE( SHAPEFile.c_str(), slope, intercept, slopeSingle, interceptSingle );
		error = checker->isErrorStatus( constraintError );

		// If no error occurred, print a message saying that SHAPE constraints are set.
		if( error == 0 ) { cout << "done." << endl; }
	}

	/*
	 * Do the efn2 calculation.
	 * If the user wants a simple output file, get free energies for each structure using the CalculateFreeEnergy method.
	 * If the user wants a thermodynamic details file, write the file with the WriteThemodynamicDetails method.
	 */
	if( error == 0 ) {

		// Write a thermodynamic details file, if asked.
		if( writeTherm ) {

			// Show a message saying that the details file is being written.
			cout << "Writing thermodynamic details file..." << flush;

			// Write the thermodynamic details file and check for errors.
			int thermError = strand->WriteThermodynamicDetails( outFile.c_str() );
			error = checker->isErrorStatus( thermError );

			// Print a message saying that the details file has been written.
			if( error == 0 ) { cout << "done." << endl; }
		}

		// Write a simple list file, if asked.
		else {

			// Show a message saying that the list file is being written.
			cout << "Writing free energy list file..." << flush;

			// For each structure, calculate its energy and push it into the energies vector.
			// Changed this 5-14-2013, no longer pushes into a vector. Instead use calculatefreeenergy method from RNA class.
			// This is so it works with openMP -- vector would be filled out of order when loop runs in parallel and the indexing would be messed up.
			// If an error occurs, set it.
			//vector<double> energies;
			strand->CalculateFreeEnergy( 1 , simple );			//calculate the free energy of the first structure first (this is to make it play well with openMP)			
			#ifdef SMP
			#pragma omp parallel for
			#endif
			for( int i = 2; i <= structures; i++ ) { 
				strand->CalculateFreeEnergy( i , simple ); 		//now calculate the free energy of the remaining structures
				error = checker->isErrorStatus();
				//if( error == 0 ) { energies.push_back( energy ); }
				//else break;
			}

			// If all free energies were calculated correctly, write the output file.
			if( error == 0 ) {
				ofstream out( outFile.c_str() );
				for( int i = 1; i <= structures; i++ ) {
					int index = i - 1;
					out << "Structure: " << i << "   Energy = " << fixed << setprecision( 1 ) << strand->GetFreeEnergy(i)  << endl; //changed to GetFreeEnergy instead of writing the energies vector
				}
				out.close();
			}

			// Print a message saying that the list file has been written.
			if( error == 0 ) { cout << "done." << endl; }

			// If the output should be piped to standard output, then pipe it.
                        if( ( error == 0 ) && ( stdPrint ) ) {
                          cout << endl << "Generated output file: " << outFile << endl << endl;
                          for( int i = 1; i <= structures; i++ ) {
	                          cout << "Structure: " << i << "   Energy = " << fixed << setprecision( 1 ) << strand->GetFreeEnergy(i) << endl;
			  }
                          cout << endl;
                        }
		}
	}

	// Delete the error checker and data structure.
	delete checker;
	delete strand;

	// Print confirmation of run finishing.
	if( error == 0 ) { cout << calcType << " complete." << endl; }
	else { cerr << calcType << " complete with errors." << endl; }
}