24b3bc3cbf288e41da1430b58c841b6fb79f2dd5
[jalview.git] / src / jalview / util / HMMProbabilityDistributionAnalyser.java
1 package jalview.util;
2
3 import jalview.datamodel.AlignmentAnnotation;
4 import jalview.datamodel.HiddenMarkovModel;
5 import jalview.datamodel.SequenceI;
6 import jalview.io.DataSourceType;
7 import jalview.io.FileParse;
8 import jalview.io.HMMFile;
9 import jalview.io.StockholmFile;
10 import jalview.schemes.ResidueProperties;
11
12 import java.io.BufferedReader;
13 import java.io.File;
14 import java.io.FileNotFoundException;
15 import java.io.FileOutputStream;
16 import java.io.FileReader;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.PrintWriter;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Random;
25 import java.util.Scanner;
26 import java.util.Vector;
27
28 /**
29  * Processes probability data. The file indexes used in this program represent
30  * the index of the location of a family or hmm in their respective files,
31  * starting from 0.
32  * 
33  * @author TZVanaalten
34  *
35  */
36 public class HMMProbabilityDistributionAnalyser
37 {
38   AlignmentAnnotation reference = null;
39
40   Vector<SequenceI> sequences;
41
42   HiddenMarkovModel hmm;
43
44   // contains the raw data produced
45   List<ArrayList<Double>> raw = new ArrayList<>();
46
47   // contains binned data
48   Map<String, Double> binned = new HashMap<>();
49
50   // location of the family file
51   String families = "/media/sf_Shared_Folder/PFAM/Family/SeedFamilies.seed";
52
53   // location of the file containing the family-clan links
54   final static String FAMILIESTOCLAN = "/media/sf_Shared_Folder/PFAM/Family/Clanlinks.dat";
55
56   // location of the HMM file
57   String hmms = "/media/sf_Shared_Folder/PFAM/HMMs/Pfam-A.hmm";
58
59   // suffix for raw file
60   final static String RAW = "/Raw.csv";
61
62   // suffix for binned file
63   final static String BINNED = "/Binned.csv";
64
65   // normalisation scale
66   final static double SCALE = 1;
67
68   // current position in file
69   int currentFilePosition = 0;
70
71   final static String NL = "\n";
72
73   Random generator = new Random();
74
75   // current directory
76   String currentFolder;
77
78   boolean keepRaw = false;
79
80   /**
81    * Sets the working directory.
82    * 
83    * @param path
84    */
85   public void setFolder(String path)
86   {
87     currentFolder = path;
88   }
89
90   /**
91    * Moves a buffered reader forward in the file by a certain amount of entries.
92    * Each entry in the file is delimited by '//'.
93    * 
94    * @param index
95    *          The index of the location in the file.
96    * @param br
97    * @throws IOException
98    */
99   public void moveLocationBy(int index, BufferedReader br)
100           throws IOException
101   {
102     for (int i = 0; i < index; i++)
103     {
104       String line = br.readLine();
105       while (!"//".equals(line))
106       {
107         line = br.readLine();
108
109       }
110     }
111
112   }
113   
114   /**
115    * Analyses a specified number of families and then saves the data. Before
116    * analysing the data, the previous saved data will be imported and after
117    * analysing this, the data is exported back into the file. The file must be
118    * in flat file format.
119    * 
120    * @param increments
121    *          The number of families to read before saving.
122    * @throws IOException
123    */
124   public void run(int increments, boolean keepRawData) throws IOException
125   {
126     keepRaw = keepRawData;
127     try
128     {
129       readPreviousData(currentFolder);
130       BufferedReader posReader = new BufferedReader(
131               new FileReader(currentFolder + "/CurrentPosition.txt"));
132
133       String line = posReader.readLine();
134       posReader.close();
135       currentFilePosition = Integer.parseInt(line);
136     } catch (Exception e)
137     {
138       System.out.println("No previous data found");
139     }
140
141
142
143     BufferedReader inputSTO = new BufferedReader(new FileReader(families));
144     BufferedReader inputHMM = new BufferedReader(new FileReader(hmms));
145
146
147
148     moveLocationBy(currentFilePosition, inputHMM);
149     moveLocationBy(currentFilePosition, inputSTO);
150
151     int filesRead = 0;
152     int i = 0;
153     while (filesRead < increments)
154     {
155
156       readStockholm(inputSTO);
157
158       readHMM(inputHMM);
159
160         int count = countValidResidues();
161         processData(count);
162         filesRead++;
163
164       currentFilePosition++;
165       System.out.println(i);
166       i++;
167     }
168
169     PrintWriter p = new PrintWriter(
170             new File(currentFolder + "/CurrentPosition.txt"));
171     p.print(currentFilePosition);
172     p.close();
173     exportData(currentFolder);
174     raw.clear();
175     binned.clear();
176
177   }
178
179   /**
180    * Analyses all families and then saves the data. Before analysing the data,
181    * the previous saved data will be imported and after analysing this, the data
182    * is exported back into the file. The file must be in flat file format.
183    * 
184    * @param increments
185    *          The number of families to read before saving.
186    * @throws IOException
187    */
188   public void runToEnd(boolean keepRawData, boolean forClans)
189           throws IOException
190   {
191     keepRaw = keepRawData;
192     BufferedReader inputSTO = null;
193     BufferedReader inputHMM = null;
194     int size = 0;
195     int files = 1;
196     try
197     {
198     if (forClans)
199     {
200         files = 603;
201     }
202     int filesRead = 0;
203     for (int clan = 0; clan < files; clan++)
204     {
205       System.out.println(clan);
206       String clanPath = "";
207       int numberOfFamilies = 0;
208       if (forClans)
209       {
210         clanPath = currentFolder + "/Clan" + clan;
211           if (!new File(clanPath).exists())
212           {
213             continue;
214           }
215         BufferedReader famCountReader = new BufferedReader(
216                 new FileReader(clanPath + "/NumberOfFamilies.txt"));
217         numberOfFamilies = Integer.parseInt(famCountReader.readLine());
218       }
219       else
220       {
221         numberOfFamilies = 1;
222       }
223       
224       for (int fam = 0; fam < numberOfFamilies; fam++)
225       {
226         if (forClans)
227         {
228           families = clanPath + "/Families/Fam" + fam + ".sto";
229           hmms = clanPath + "/HMMs/HMM" + fam + ".hmm";
230         }
231
232         inputSTO = new BufferedReader(new FileReader(families));
233         inputHMM = new BufferedReader(new FileReader(hmms));
234
235
236         int i = 0;
237         boolean endReached = atEnd(inputSTO);
238         while (!endReached)
239         {
240           readStockholm(inputSTO);
241           readHMM(inputHMM);
242
243         int count = countValidResidues();
244         processData(count);
245         filesRead++;
246           System.out.println(filesRead);
247       endReached = atEnd(inputSTO);
248       }
249       }
250     }
251     } catch (Exception e)
252     {
253       e.printStackTrace();
254     } finally
255     {
256       exportData(currentFolder);
257       raw.clear();
258       binned.clear();
259     }
260   }
261
262   /**
263    * Reads the previous data from both files
264    * 
265    * @param source
266    * @throws IOException
267    */
268   public void readPreviousData(String source) throws IOException
269   {
270     readBinned(source);
271     if (keepRaw)
272     {
273       readRaw(source);
274     }
275   }
276
277   /**
278    * Reads the previous data from the binned file.
279    * 
280    * @param source
281    * @throws IOException
282    */
283   public void readBinned(String source) throws IOException
284   {
285     BufferedReader input = new BufferedReader(
286             new FileReader(source + BINNED));
287     String line = input.readLine();
288     binned = new HashMap<>();
289     while (!("".equals(line) || line == null))
290     {
291       Scanner scanner = new Scanner(line);
292       scanner.useDelimiter(",");
293       String key = scanner.next();
294       String value = scanner.next();
295       binned.put(key, Double.valueOf(value));
296       scanner.close();
297       line = input.readLine();
298     }
299
300     input.close();
301   }
302
303   /**
304    * Reads the previous data from the raw file.
305    * 
306    * @param source
307    * @throws IOException
308    */
309   public void readRaw(String source) throws IOException
310   {
311     BufferedReader input = new BufferedReader(new FileReader(source + RAW));
312     String line = input.readLine();
313     if (line == null)
314     {
315       input.close();
316       return;
317     }
318     Scanner numberScanner = new Scanner(line);
319     numberScanner.useDelimiter(",");
320     raw = new ArrayList<>();
321     while (numberScanner.hasNext())
322     {
323       numberScanner.next();
324       raw.add(new ArrayList<Double>());
325     }
326     numberScanner.close();
327
328     line = input.readLine();
329     while (!("".equals(line) || line == null))
330     {
331       Scanner scanner = new Scanner(line);
332       scanner.useDelimiter(",");
333
334       int i = 0;
335       while (scanner.hasNext())
336       {
337         String value;
338         value = scanner.next();
339         if (!value.equals("EMPTY"))
340         {
341           raw.get(i).add(Double.parseDouble(value));
342         }
343         else
344         {
345           raw.get(i).add(null);
346         }
347
348         i++;
349       }
350       scanner.close();
351       line = input.readLine();
352     }
353
354     input.close();
355   }
356
357   /**
358    * Counts the number of valid residues in the sequence.
359    * 
360    * @return
361    */
362   public int countValidResidues()
363   {
364     int count = 0;
365
366     for (int width = 0; width < sequences.size(); width++)
367     {
368       for (int length = 1; length < hmm.getLength() + 1; length++)
369       {
370         char symbol;
371         int alignPos;
372         alignPos = hmm.getNodeAlignmentColumn(length);
373
374         symbol = sequences.get(width).getCharAt(alignPos);
375         if (ResidueProperties.aminoBackgroundFrequencies
376                 .containsKey(symbol))
377         {
378           count++;
379         }
380       }
381     }
382
383     return count;
384   }
385
386   /**
387    * Processes data, and stores it in both a raw and binned format.
388    * 
389    * @param count
390    */
391   public void processData(int count)
392   {
393     int rawPos = 0;
394     if (keepRaw)
395     {
396       raw.add(new ArrayList<Double>());
397       rawPos = raw.size() - 1;
398     }
399     Double total = 0d;
400     for (int width = 0; width < sequences.size(); width++)
401     {
402       for (int length = 1; length < hmm.getLength() + 1; length++)
403       {
404         char symbol;
405         int alignPos;
406         alignPos = hmm.getNodeAlignmentColumn(length);
407         
408         symbol = sequences.get(width).getCharAt(alignPos);
409         if (ResidueProperties.aminoBackgroundFrequencies
410                 .containsKey(symbol))
411         {
412           Double prob;
413           Float bfreq;
414           Double llr;
415           prob = hmm.getMatchEmissionProbability(alignPos, symbol);
416           bfreq = ResidueProperties.aminoBackgroundFrequencies.get(symbol);
417           if (prob == 0 || bfreq == 0)
418           {
419             System.out.println("error");
420           }
421           llr = Math.log(prob / bfreq);
422           if (keepRaw)
423           {
424             raw.get(rawPos).add(llr);
425           }
426
427           String output;
428           output = String.format("%.1f", llr);
429           total += Double.parseDouble(output);
430           if ("-0.0".equals(output))
431           {
432             output = "0.0";
433           }
434           if (binned.containsKey(output))
435           {
436             double prev = binned.get(output);
437             prev += (SCALE / count);
438             binned.put(output, prev);
439
440           }
441           else
442           {
443             binned.put(output, SCALE / count);
444           }
445         }
446       }
447     }
448     System.out.println(total / count);
449   }
450
451
452   /**
453    * Reads in the sequence data from a Stockholm file.
454    * 
455    * @param source
456    * @throws IOException
457    */
458   public void readStockholm(BufferedReader inputSTO) throws IOException
459   {
460     FileParse parserSTO = new FileParse(inputSTO, "", DataSourceType.FILE);
461     StockholmFile file = new StockholmFile(parserSTO);
462     Vector<AlignmentAnnotation> annots = file.getAnnotations();
463
464     for (AlignmentAnnotation annot : annots)
465     {
466       if (annot.label.contains("Reference"))
467       {
468         reference = annot;
469       }
470     }
471     sequences = file.getSeqs();
472   }
473
474   /**
475    * Reads in the HMM data from a HMMer file.
476    * 
477    * @param source
478    * @throws IOException
479    */
480   public void readHMM(BufferedReader inputHMM) throws IOException
481   {
482     FileParse parserHMM = new FileParse(inputHMM, "", DataSourceType.FILE);
483     HMMFile file = new HMMFile(parserHMM);
484     hmm = file.getHMM();
485
486
487   }
488
489   /**
490    * Exports both the binned and raw data into separate files.
491    * 
492    * @param location
493    * @throws FileNotFoundException
494    */
495   public void exportData(String location) throws FileNotFoundException
496   {
497     PrintWriter writerBin = new PrintWriter(new File(location + BINNED));
498     for (Map.Entry<String, Double> entry : binned.entrySet())
499     {
500       writerBin.println(entry.getKey() + "," + entry.getValue());
501     }
502     writerBin.close();
503     if (keepRaw)
504     {
505
506     PrintWriter writerRaw = new PrintWriter(new File(location + RAW));
507     
508     StringBuilder identifier = new StringBuilder();
509     
510     for (int i = 1; i < raw.size() + 1; i++)
511     {
512       identifier.append("Fam " + i + ",");
513     }
514     
515     writerRaw.println(identifier);
516     
517     boolean rowIsEmpty = false;
518     int row = 0;
519     while (!rowIsEmpty)
520     {
521       rowIsEmpty = true;
522       StringBuilder string = new StringBuilder();
523       for (int column = 0; column < raw.size(); column++)
524       {
525         if (raw.get(column).size() <= row)
526         {
527           string.append("EMPTY,");
528         }
529         else
530         {
531           string.append(raw.get(column).get(row) + ",");
532           rowIsEmpty = false;
533         }
534       }
535       row++;
536       writerRaw.println(string);
537     }
538     writerRaw.close();
539
540     }
541
542   }
543
544   /**
545    * Prints the specified family on the console.
546    * 
547    * @param index
548    * @throws IOException
549    */
550   public void printFam(int index) throws IOException
551   {
552     BufferedReader br = new BufferedReader(new FileReader(families));
553
554     moveLocationBy(index, br);
555
556     String line = br.readLine();
557
558     while (!"//".equals(line))
559     {
560       System.out.println(line);
561       line = br.readLine();
562     }
563     System.out.println(line);
564     br.close();
565
566   }
567
568   /**
569    * Prints the specified HMM on the console.
570    * 
571    * @param index
572    * @throws IOException
573    */
574   public void printHMM(int index) throws IOException
575   {
576     BufferedReader br = new BufferedReader(new FileReader(hmms));
577
578     moveLocationBy(index, br);
579
580     String line = br.readLine();
581
582     while (!"//".equals(line))
583     {
584       System.out.println(line);
585       line = br.readLine();
586     }
587     System.out.println(line);
588     br.close();
589
590   }
591
592   /**
593    * Prints the specified family to a .sto file.
594    * 
595    * @param index
596    * @throws IOException
597    */
598   public void exportFam(int index, String location) throws IOException
599   {
600     BufferedReader br = new BufferedReader(new FileReader(families));
601
602     moveLocationBy(index, br);
603
604     String line = br.readLine();
605     PrintWriter writer = new PrintWriter(
606             new FileOutputStream(new File(location), true));
607     while (!"//".equals(line))
608     {
609       writer.println(line);
610       line = br.readLine();
611     }
612     writer.println(line);
613     writer.close();
614     br.close();
615
616   }
617
618   public void exportFile(BufferedReader br, String location, boolean append)
619           throws IOException
620   {
621     String line = br.readLine();
622     PrintWriter writer = new PrintWriter(
623             new FileOutputStream(location, append));
624     while (!"//".equals(line))
625     {
626       writer.println(line);
627       line = br.readLine();
628     }
629     writer.println(line);
630     writer.close();
631
632
633   }
634
635   public String getHMMName(int index) throws IOException
636   {
637     String name;
638
639     BufferedReader nameFinder = new BufferedReader(new FileReader(hmms));
640
641     moveLocationBy(index, nameFinder);
642
643     nameFinder.readLine();
644
645     Scanner scanner = new Scanner(nameFinder.readLine());
646     name = scanner.next();
647     name = scanner.next();
648     scanner.close();
649     return name;
650   }
651
652   public String getFamilyName(int index) throws IOException
653   {
654     String name;
655
656     BufferedReader nameFinder = new BufferedReader(
657             new FileReader(families));
658
659     moveLocationBy(index, nameFinder);
660
661     nameFinder.readLine();
662
663     Scanner scanner = new Scanner(nameFinder.readLine());
664     name = scanner.next();
665     name = scanner.next();
666     name = scanner.next();
667     scanner.close();
668     return name;
669   }
670
671   /**
672    * Prints the specified family to a .hmm file.
673    * 
674    * @param index
675    * @throws IOException
676    */
677   public void exportHMM(int index, String location) throws IOException
678   {
679
680
681     BufferedReader br = new BufferedReader(new FileReader(hmms));
682
683     moveLocationBy(index, br);
684
685     String line = br.readLine();
686
687     PrintWriter writer = new PrintWriter(
688             new FileOutputStream(new File(location), true));
689     while (!"//".equals(line))
690     {
691       writer.println(line);
692       line = br.readLine();
693     }
694     writer.println(line);
695     writer.close();
696     br.close();
697
698   }
699   
700   /**
701    * Clears all raw, binned and current position data in the current directory.
702    * 
703    * @throws FileNotFoundException
704    */
705   public void clear() throws FileNotFoundException
706   {
707     PrintWriter pos = new PrintWriter(
708             currentFolder + "/CurrentPosition.txt");
709     pos.println("0");
710     
711     PrintWriter raw = new PrintWriter(currentFolder + RAW);
712     
713     PrintWriter bin = new PrintWriter(currentFolder + BINNED);
714     
715     pos.close();
716     bin.close();
717     raw.close();
718   }
719
720   public void sortIntoClans(String directory) throws IOException
721   {
722     BufferedReader clanFinder = new BufferedReader(new FileReader(FAMILIESTOCLAN));
723     BufferedReader familyReader = new BufferedReader(
724             new FileReader(families));
725     BufferedReader hmmReader = new BufferedReader(new FileReader(hmms));
726     int families = 0;
727     // moveLocationBy(7000, familyReader);
728     // moveLocationBy(7000, clanFinder);
729     // moveLocationBy(7000, hmmReader);
730     HashMap<String, Integer> clanIndexes = new HashMap<>();
731     ArrayList<Integer> familyCounts = new ArrayList<>();
732     int filePos = 0; 
733     int clanCount = 0;
734     String line;
735     line = clanFinder.readLine();
736     
737     while (!"".equals(line) && !" ".equals(line) && line != null)
738     {
739      String clanName;
740       boolean inClan = false;
741      while (!(line.indexOf("//") > -1))
742      {
743        
744       if (line.indexOf("#=GF CL") > -1)
745       {
746           families++;
747           System.out.println(families);
748           inClan = true;
749         Scanner scanner = new Scanner(line);
750         scanner.next();
751         scanner.next();
752         clanName = scanner.next();
753           scanner.close();
754         
755         if (!clanIndexes.containsKey(clanName))
756         {
757           clanIndexes.put(clanName, clanCount);
758             clanCount++;
759             familyCounts.add(0);
760         }
761
762
763           Integer clanI = clanIndexes.get(clanName);
764           String clanPath = directory + "/Clan" + clanI.toString();
765           createFolders(clanPath);
766
767           int index = clanIndexes.get(clanName);
768           exportFile(familyReader,
769                   clanPath + "/Families/Fam" + familyCounts.get(index)
770                           + ".sto",
771                   false);
772           exportFile(hmmReader,
773                   clanPath + "/HMMs/HMM" + familyCounts.get(index) + ".hmm",
774                   false);
775
776           int count = familyCounts.get(index);
777           count++;
778           familyCounts.set(index, count);
779       }
780         line = clanFinder.readLine();
781
782       }
783       if (!inClan)
784       {
785         moveLocationBy(1, familyReader);
786         moveLocationBy(1, hmmReader);
787       }
788       filePos++;
789       // System.out.println(filePos + " files read.");
790       line = clanFinder.readLine();
791
792      }
793     clanFinder.close();
794
795     for (int clan = 0; clan < clanCount; clan++)
796     {
797       PrintWriter writer = new PrintWriter(
798               directory + "/Clan" + clan + "/NumberOfFamilies.txt");
799       int count = familyCounts.get(clan);
800       writer.print(count);
801       writer.close();
802     }
803       
804     }
805
806   public String getFamilies()
807   {
808     return families;
809   }
810
811   public void setFamilies(String families)
812   {
813     this.families = currentFolder + families;
814   }
815
816   public String getHmms()
817   {
818     return hmms;
819   }
820
821   public void setHmms(String hmms)
822   {
823     this.hmms = currentFolder + hmms;
824   }
825     
826   public void alignWithinClan(String exportLocation, String clansLocation)
827           throws IOException, InterruptedException
828   {
829     int alignmentsExported = 0;
830     for (int clan = 0; clan < 604; clan++)
831     {
832       System.out.println(clan);
833       int famCount = 0;
834       String clanPath = clansLocation + "/Clan" + clan;
835       int numberOfFamilies;
836       BufferedReader br = new BufferedReader(
837               new FileReader(clanPath + "/NumberOfFamilies.txt"));
838       String line = br.readLine();
839       numberOfFamilies = Integer.parseInt(line);
840       br.close();
841       if (numberOfFamilies == 1)
842       {
843         continue;
844       }
845       final String commandExportLocation = exportLocation + "/Clan" + clan;
846       createFolders(commandExportLocation);
847       for (int family = 0; family < numberOfFamilies; family++)
848       {
849         famCount++;
850         ArrayList<Integer> indexes = new ArrayList<>();
851         for (int i = 0; i < numberOfFamilies; i++)
852         {
853           if (i != family)
854           {
855             indexes.add(i);
856           }
857         }
858
859         int hmmIndex = getRandom(indexes);
860         String famPath = clanPath + "/Families/Fam" + family + ".sto";
861         String hmmPath = clanPath + "/HMMs/HMM" + hmmIndex + ".hmm";
862         String command = "/media/sf_Shared_Folder/hmmer/binaries/hmmalign --mapali "
863                 + clanPath + "/Families/Fam" + hmmIndex + ".sto"
864                 + " --trim ";
865         command += hmmPath + " ";
866         command += famPath;
867         final int familyIndex = family;
868         final Process p = Runtime.getRuntime().exec(command);
869
870         new Thread(new Runnable()
871         {
872           @Override
873           public void run()
874           {
875             BufferedReader input = new BufferedReader(
876                     new InputStreamReader(p.getInputStream()));
877             String line = null;
878
879             try
880             {
881               PrintWriter writer = new PrintWriter(commandExportLocation
882                       + "/Families/Fam" + familyIndex + ".sto");
883               String lastLine = "";
884               boolean dataFound = false;
885               while ((line = input.readLine()) != null)
886               {
887                 if (line.contains("#=GR") && !dataFound)
888                 {
889                   writer.println(lastLine);
890                   dataFound = true;
891                 }
892                 if (line.contains("#") || dataFound || " ".equals(line)
893                         || "".equals(line) || "//".equals(line))
894                 {
895                   writer.println(line);
896                 }
897                 lastLine = line;
898               }
899               writer.close();
900             } catch (IOException e)
901             {
902               e.printStackTrace();
903             }
904           }
905         }).start();
906
907         p.waitFor();
908
909         BufferedReader hmmExporter = new BufferedReader(
910                 new FileReader(hmmPath));
911
912         exportFile(hmmExporter,
913                 commandExportLocation + "/HMMs/HMM" + family + ".hmm",
914                 false);
915
916         alignmentsExported++;
917
918
919       }
920       PrintWriter writer = new PrintWriter(
921               commandExportLocation + "/NumberOfFamilies.txt");
922       writer.print(famCount);
923       writer.close();
924     }
925
926   }
927
928   public boolean atEnd(BufferedReader br) throws IOException
929   {
930     boolean end = false;
931     br.mark(80);
932     String line = br.readLine();
933     if ("".equals(line) || line == null)
934     {
935       end = true;
936     }
937     br.reset();
938     return end;
939   }
940
941   public int getRandom(ArrayList<Integer> list)
942   {
943     if (!(list.size() > 0))
944     {
945       System.out.println("Error - size = " + list.size());
946     }
947     int index = generator.nextInt(list.size());
948     int value = list.get(index);
949     list.remove(index);
950     return value;
951   }
952
953   public void createFolders(String clanPath)
954   {
955     File clanFolder = new File(clanPath);
956     if (!clanFolder.exists())
957     {
958       clanFolder.mkdir();
959     }
960
961     File famFolder = new File(clanPath + "/Families");
962     File hmmFolder = new File(clanPath + "/HMMs");
963     if (!famFolder.exists())
964     {
965       famFolder.mkdir();
966       hmmFolder.mkdir();
967     }
968   }
969 }
970
971
972
973