make mupa file loading eol-style insensitive
[mussa.git] / alg / mussa.hpp
index 55547ec7cc3d60598b0f85a80da820d533aa15d8..152d8217349568755913e67c1a77fed6aaa6eaa6 100644 (file)
 //                        ----------------------------------------
 //                          ---------- mussa_class.hh -----------
 //                        ----------------------------------------
-#include <QObject> 
+#include <QObject>
+#include <QString> 
 
 #include <boost/filesystem/path.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <list>
 #include <string>
 
 std::string int_to_str(int an_int);
 
+class Mussa;
+//! provide a simple name to point to our Mussa shared_ptr
+typedef boost::shared_ptr<Mussa> MussaRef;
+
 class Mussa : public QObject
 {
     Q_OBJECT 
 
 signals:
     //! call whatever signaling system we want
-    void progress(const std::string& description, int cur, int max);
+    void progress(const QString& description, int cur, int max);
+    //! triggered when our state changes between unsaved(true) and saved(false)
+    void isModified(bool);
 
 public:
+    typedef std::set<Sequence> motif_set;
     enum analysis_modes { TransitiveNway, RadialNway, EntropyNway, 
                           RecursiveNway };
 
     Mussa();
     Mussa(const Mussa &);
 
-    void save();
+    //! dynamically construct a new Mussa object and return a reference to it
+    static MussaRef init();
+    
+    //! save all of mussa
+    void save(boost::filesystem::path save_path="");
     //! save the nway comparison
     void save_muway(boost::filesystem::path save_path);
     //! load a saved analysis directory
     void load(boost::filesystem::path ana_path);
+    // ! return path to the where the analysis is stored
+    boost::filesystem::path get_analysis_path() const;
+    //! set analysis path
+    void set_analysis_path(boost::filesystem::path);
 
     //! clear parameters and initialize data lists
     void clear();
 
     //! set parameters from a file - 'mupa' ~ mussa parameters
-    void load_mupa_file(std::string para_file_path) { load_mupa_file(boost::filesystem::path(para_file_path));}
+    void load_mupa_file(std::string para_file_path);
     void load_mupa_file(boost::filesystem::path para_file_path);
+    //! load mussa parameters from a stream, specifing output location
+    void load_mupa_stream(
+           std::istream & para_file, 
+           boost::filesystem::path& file_path_base
+         );
+    
 
     // set parameters individually (eg from user input into gui classes)
     //! set analysis name
     void set_name(std::string a_name);
     //! return name for this analysis
-    std::string get_name();
+    std::string get_name() const;
+    //! return a reasonable window title for this analysis
+    /*! this returns the "variable" portion for a title
+     */
+    std::string get_title() const;
 
     //! return number of sequences in this analyzis
     /*! this returns either the_seqs.size() or seq_files.size()
@@ -89,6 +116,12 @@ public:
     enum analysis_modes get_analysis_mode() const;
     //! return a string name for an analysis mode
     std::string get_analysis_mode_name() const;
+    //! set our current dirty state
+    void set_dirty(bool);
+    //! return if we have unsaved changes
+    bool is_dirty() const;
+    //! is there anything loaded into this analysis?
+    bool empty() const;
 
     //! return the refined paths found by the nway analysis.
     const NwayPaths& paths() const;
@@ -112,7 +145,12 @@ public:
     void nway();
 
     //! appends a string sequence to the list of the_seqs
-    void add_a_seq(std::string a_seq);
+    // void append_sequence(std::string a_seq);
+    //! appends a sequence to the list of the_seqs (makes copy)
+    void append_sequence(const Sequence& a_seq);
+    //! append a sequence to the list of seqs (shared)
+    void append_sequence(boost::shared_ptr<Sequence> a_seq);
+
     //! Load a sequence from a fasta file and any annotations
     /*! \param[in] seq_file the full path to the fasta file
      *  \param[in] annot_file the full path to an annotation file,
@@ -123,41 +161,53 @@ public:
      *             use 0 start from the beginning.
      *  \param[in] sub_seq_end ending slice index to select a subsequence
      *             use 0 to go to the end.
+     *  \param[in] name sequence name, only used if not null
      */
     void load_sequence(boost::filesystem::path seq_file, 
                        boost::filesystem::path annot_file, 
-                       int fasta_index, int sub_seq_start=0, int sub_seq_end=0);
+                       int fasta_index, int sub_seq_start=0, int sub_seq_end=0,
+                       std::string *name=0);
     //! allow examining the sequences we have loaded
-    const std::vector<Sequence>& sequences() const;
+    typedef std::vector<boost::shared_ptr<Sequence> > vector_sequence_type;
+    const vector_sequence_type& sequences() const;
 
     // deprecated - support bridge for python version of mussa
     // these save & load from the old file format
     void save_old();
     void load_old(char * load_file_path, int s_num);
 
-    // manage motif lists
-    //! add vector of motifs and colors to our motif collection
-    /*! this depends on sets and color maps being unique
+    // manage motif lists 
+    //! add a motif it wont be applied until update_sequences_motif is called
+    void add_motif(const Sequence& motifs, const Color& colors);
+    //! add vector of motifs and colors to our motif collection 
+    /*! this will automatically call update_sequences_motif
+     *  this depends on sets and color maps being unique
      *  (aka if you add the same item more than once it doesn't
-     *  increase the size of the data structure
+     *  increase the size of the data structure)
      */
-    void add_motifs(const std::vector<std::string>& motifs, 
+    void set_motifs(const std::vector<Sequence>& motifs, 
                     const std::vector<Color>& colors);
-    //! load motifs from an ifstream
     /*! The file should look something like
      *  <sequence> <red> <green> <blue>
      *  where sequence is a string of IUPAC symbols
      *  and red,green,blue are a white space separated list of floats
      *  in the range [0.0, 1.0]
      */
-    void load_motifs(std::istream &);
     //! load a list of motifs from a file named filename
     void load_motifs(boost::filesystem::path filename);
+    //! load motifs from an ifstream
+    /*! \sa Mussa::load_motifs(boost::filesystem::path)
+     */
+    void load_motifs(std::istream &);
+    //! save motif list to the specified filename
+    void save_motifs(boost::filesystem::path filename);
+    //! save motif list to an ostream
+    void save_motifs(std::ostream &);
     //! return our motifs;
-    const std::set<std::string>& motifs() const;
+    const motif_set& motifs() const;
 
     //! return color mapper
-    AnnotationColors& colorMapper();
+    boost::shared_ptr<AnnotationColors> colorMapper();
 
   private:
     //! push motifs to our attached sequences
@@ -171,6 +221,7 @@ public:
     int window;
     //! how many base pairs need to match order to record a window as conserved
     int threshold;
+    //! stores current filter used by GUI to change the connections shown
     int soft_thres;
     //! which nway comparison algorithm to use.
     enum analysis_modes ana_mode;
@@ -181,16 +232,20 @@ public:
     bool thres_append;
 
     //! sequence data
-    std::vector<Sequence> the_seqs;
+    vector_sequence_type the_seqs;
     //! the seqcomp data
     std::vector<std::vector<FLPs> > all_comps;
     //! N-way data, ie the mussa results  
     NwayPaths the_paths;
 
     //! motif list
-    std::set<std::string> motif_sequences;
+    motif_set motif_sequences;
     //! color manager
-    AnnotationColors color_mapper;
+    boost::shared_ptr<AnnotationColors> color_mapper;
+    //! path to our analysis
+    boost::filesystem::path analysis_path;
+    //! flag indicating if we have unsaved changes
+    bool dirty;
 
     // Private methods
     //! runs all the seqcomps needed to support the nway comparison