7d6687817a008aba47aa9f5ed3c2520e9c5e0de8
[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 = "H:/Desktop//PFAM/Family/SeedFamilies.seed";
52
53   // location of the file containing the family-clan links
54   final static String FAMILIESTOCLAN = "H:/Desktop//PFAM/Family/Clanlinks.dat";
55
56   // location of the HMM file
57   String hmms = "H:/Desktop//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     if (forClans)
197     {
198       files = 604;
199     }
200     int filesRead = 0;
201     for (int clan = 0; clan < files; clan++)
202     {
203       String clanPath = "";
204       int numberOfFamilies = 0;
205       if (forClans)
206       {
207         clanPath = currentFolder + "/Clan" + clan;
208         BufferedReader famCountReader = new BufferedReader(
209                 new FileReader(clanPath + "/NumberOfFamilies.txt"));
210         numberOfFamilies = Integer.parseInt(famCountReader.readLine());
211       }
212       else
213       {
214         numberOfFamilies = 1;
215       }
216       
217       for (int fam = 0; fam < numberOfFamilies; fam++)
218       {
219         if (forClans)
220         {
221           families = clanPath + "/Families/Fam" + fam + ".sto";
222           hmms = clanPath + "/HMMs/HMM" + fam + ".hmm";
223         }
224
225         inputSTO = new BufferedReader(new FileReader(families));
226         inputHMM = new BufferedReader(new FileReader(hmms));
227
228
229         int i = 0;
230         boolean endReached = atEnd(inputSTO);
231         while (!endReached)
232         {
233           readStockholm(inputSTO);
234           readHMM(inputHMM);
235
236         int count = countValidResidues();
237         processData(count);
238         filesRead++;
239           System.out.println(filesRead);
240       endReached = atEnd(inputSTO);
241       }
242       }
243     }
244     exportData(currentFolder);
245     raw.clear();
246     binned.clear();
247   }
248
249   /**
250    * Reads the previous data from both files
251    * 
252    * @param source
253    * @throws IOException
254    */
255   public void readPreviousData(String source) throws IOException
256   {
257     readBinned(source);
258     if (keepRaw)
259     {
260       readRaw(source);
261     }
262   }
263
264   /**
265    * Reads the previous data from the binned file.
266    * 
267    * @param source
268    * @throws IOException
269    */
270   public void readBinned(String source) throws IOException
271   {
272     BufferedReader input = new BufferedReader(
273             new FileReader(source + BINNED));
274     String line = input.readLine();
275     binned = new HashMap<>();
276     while (!("".equals(line) || line == null))
277     {
278       Scanner scanner = new Scanner(line);
279       scanner.useDelimiter(",");
280       String key = scanner.next();
281       String value = scanner.next();
282       binned.put(key, Double.valueOf(value));
283       scanner.close();
284       line = input.readLine();
285     }
286
287     input.close();
288   }
289
290   /**
291    * Reads the previous data from the raw file.
292    * 
293    * @param source
294    * @throws IOException
295    */
296   public void readRaw(String source) throws IOException
297   {
298     BufferedReader input = new BufferedReader(new FileReader(source + RAW));
299     String line = input.readLine();
300     if (line == null)
301     {
302       input.close();
303       return;
304     }
305     Scanner numberScanner = new Scanner(line);
306     numberScanner.useDelimiter(",");
307     raw = new ArrayList<>();
308     while (numberScanner.hasNext())
309     {
310       numberScanner.next();
311       raw.add(new ArrayList<Double>());
312     }
313     numberScanner.close();
314
315     line = input.readLine();
316     while (!("".equals(line) || line == null))
317     {
318       Scanner scanner = new Scanner(line);
319       scanner.useDelimiter(",");
320
321       int i = 0;
322       while (scanner.hasNext())
323       {
324         String value;
325         value = scanner.next();
326         if (!value.equals("EMPTY"))
327         {
328           raw.get(i).add(Double.parseDouble(value));
329         }
330         else
331         {
332           raw.get(i).add(null);
333         }
334
335         i++;
336       }
337       scanner.close();
338       line = input.readLine();
339     }
340
341     input.close();
342   }
343
344   /**
345    * Counts the number of valid residues in the sequence.
346    * 
347    * @return
348    */
349   public int countValidResidues()
350   {
351     int count = 0;
352
353     for (int width = 0; width < sequences.size(); width++)
354     {
355       for (int length = 1; length < hmm.getLength() + 1; length++)
356       {
357         char symbol;
358         int alignPos;
359         alignPos = hmm.getNodeAlignmentColumn(length);
360
361         symbol = sequences.get(width).getCharAt(alignPos);
362         if (ResidueProperties.aminoBackgroundFrequencies
363                 .containsKey(symbol))
364         {
365           count++;
366         }
367       }
368     }
369
370     return count;
371   }
372
373   /**
374    * Processes data, and stores it in both a raw and binned format.
375    * 
376    * @param count
377    */
378   public void processData(int count)
379   {
380     int rawPos = 0;
381     if (keepRaw)
382     {
383       raw.add(new ArrayList<Double>());
384       rawPos = raw.size() - 1;
385     }
386
387     for (int width = 0; width < sequences.size(); width++)
388     {
389       for (int length = 1; length < hmm.getLength() + 1; length++)
390       {
391         char symbol;
392         int alignPos;
393         alignPos = hmm.getNodeAlignmentColumn(length);
394         
395         symbol = sequences.get(width).getCharAt(alignPos);
396         if (ResidueProperties.aminoBackgroundFrequencies
397                 .containsKey(symbol))
398         {
399           Double prob;
400           Float bfreq;
401           Double llr;
402           prob = hmm.getMatchEmissionProbability(alignPos, symbol);
403           bfreq = ResidueProperties.aminoBackgroundFrequencies.get(symbol);
404           llr = Math.log(prob / bfreq);
405           if (keepRaw)
406           {
407             raw.get(rawPos).add(llr);
408           }
409
410           String output;
411           output = String.format("%.1f", llr);
412           if ("-0.0".equals(output))
413           {
414             output = "0.0";
415           }
416           if (binned.containsKey(output))
417           {
418             double prev = binned.get(output);
419             prev += (SCALE / count);
420             binned.put(output, prev);
421
422           }
423           else
424           {
425             binned.put(output, SCALE / count);
426           }
427         }
428       }
429     }
430   }
431
432
433   /**
434    * Reads in the sequence data from a Stockholm file.
435    * 
436    * @param source
437    * @throws IOException
438    */
439   public void readStockholm(BufferedReader inputSTO) throws IOException
440   {
441     FileParse parserSTO = new FileParse(inputSTO, "", DataSourceType.FILE);
442     StockholmFile file = new StockholmFile(parserSTO);
443     Vector<AlignmentAnnotation> annots = file.getAnnotations();
444
445     for (AlignmentAnnotation annot : annots)
446     {
447       if (annot.label.contains("Reference"))
448       {
449         reference = annot;
450       }
451     }
452     sequences = file.getSeqs();
453   }
454
455   /**
456    * Reads in the HMM data from a HMMer file.
457    * 
458    * @param source
459    * @throws IOException
460    */
461   public void readHMM(BufferedReader inputHMM) throws IOException
462   {
463     FileParse parserHMM = new FileParse(inputHMM, "", DataSourceType.FILE);
464     HMMFile file = new HMMFile(parserHMM);
465     file.parse();
466     hmm = file.getHMM();
467
468     if (reference != null)
469     {
470       hmm.mapToReferenceAnnotation(reference);
471     }
472
473   }
474
475   /**
476    * Exports both the binned and raw data into separate files.
477    * 
478    * @param location
479    * @throws FileNotFoundException
480    */
481   public void exportData(String location) throws FileNotFoundException
482   {
483     PrintWriter writerBin = new PrintWriter(new File(location + BINNED));
484     for (Map.Entry<String, Double> entry : binned.entrySet())
485     {
486       writerBin.println(entry.getKey() + "," + entry.getValue());
487     }
488     writerBin.close();
489     if (keepRaw)
490     {
491
492     PrintWriter writerRaw = new PrintWriter(new File(location + RAW));
493     
494     StringBuilder identifier = new StringBuilder();
495     
496     for (int i = 1; i < raw.size() + 1; i++)
497     {
498       identifier.append("Fam " + i + ",");
499     }
500     
501     writerRaw.println(identifier);
502     
503     boolean rowIsEmpty = false;
504     int row = 0;
505     while (!rowIsEmpty)
506     {
507       rowIsEmpty = true;
508       StringBuilder string = new StringBuilder();
509       for (int column = 0; column < raw.size(); column++)
510       {
511         if (raw.get(column).size() <= row)
512         {
513           string.append("EMPTY,");
514         }
515         else
516         {
517           string.append(raw.get(column).get(row) + ",");
518           rowIsEmpty = false;
519         }
520       }
521       row++;
522       writerRaw.println(string);
523     }
524     writerRaw.close();
525
526     }
527
528   }
529
530   /**
531    * Prints the specified family on the console.
532    * 
533    * @param index
534    * @throws IOException
535    */
536   public void printFam(int index) throws IOException
537   {
538     BufferedReader br = new BufferedReader(new FileReader(families));
539
540     moveLocationBy(index, br);
541
542     String line = br.readLine();
543
544     while (!"//".equals(line))
545     {
546       System.out.println(line);
547       line = br.readLine();
548     }
549     System.out.println(line);
550     br.close();
551
552   }
553
554   /**
555    * Prints the specified HMM on the console.
556    * 
557    * @param index
558    * @throws IOException
559    */
560   public void printHMM(int index) throws IOException
561   {
562     BufferedReader br = new BufferedReader(new FileReader(hmms));
563
564     moveLocationBy(index, br);
565
566     String line = br.readLine();
567
568     while (!"//".equals(line))
569     {
570       System.out.println(line);
571       line = br.readLine();
572     }
573     System.out.println(line);
574     br.close();
575
576   }
577
578   /**
579    * Prints the specified family to a .sto file.
580    * 
581    * @param index
582    * @throws IOException
583    */
584   public void exportFam(int index, String location) throws IOException
585   {
586     BufferedReader br = new BufferedReader(new FileReader(families));
587
588     moveLocationBy(index, br);
589
590     String line = br.readLine();
591     PrintWriter writer = new PrintWriter(
592             new FileOutputStream(new File(location), true));
593     while (!"//".equals(line))
594     {
595       writer.println(line);
596       line = br.readLine();
597     }
598     writer.println(line);
599     writer.close();
600     br.close();
601
602   }
603
604   public void exportFile(BufferedReader br, String location, boolean append)
605           throws IOException
606   {
607     String line = br.readLine();
608     PrintWriter writer = new PrintWriter(
609             new FileOutputStream(location, append));
610     while (!"//".equals(line))
611     {
612       writer.println(line);
613       line = br.readLine();
614     }
615     writer.println(line);
616     writer.close();
617
618
619   }
620
621   public String getHMMName(int index) throws IOException
622   {
623     String name;
624
625     BufferedReader nameFinder = new BufferedReader(new FileReader(hmms));
626
627     moveLocationBy(index, nameFinder);
628
629     nameFinder.readLine();
630
631     Scanner scanner = new Scanner(nameFinder.readLine());
632     name = scanner.next();
633     name = scanner.next();
634     scanner.close();
635     return name;
636   }
637
638   public String getFamilyName(int index) throws IOException
639   {
640     String name;
641
642     BufferedReader nameFinder = new BufferedReader(
643             new FileReader(families));
644
645     moveLocationBy(index, nameFinder);
646
647     nameFinder.readLine();
648
649     Scanner scanner = new Scanner(nameFinder.readLine());
650     name = scanner.next();
651     name = scanner.next();
652     name = scanner.next();
653     scanner.close();
654     return name;
655   }
656
657   /**
658    * Prints the specified family to a .hmm file.
659    * 
660    * @param index
661    * @throws IOException
662    */
663   public void exportHMM(int index, String location) throws IOException
664   {
665
666
667     BufferedReader br = new BufferedReader(new FileReader(hmms));
668
669     moveLocationBy(index, br);
670
671     String line = br.readLine();
672
673     PrintWriter writer = new PrintWriter(
674             new FileOutputStream(new File(location), true));
675     while (!"//".equals(line))
676     {
677       writer.println(line);
678       line = br.readLine();
679     }
680     writer.println(line);
681     writer.close();
682     br.close();
683
684   }
685   
686   /**
687    * Clears all raw, binned and current position data in the current directory.
688    * 
689    * @throws FileNotFoundException
690    */
691   public void clear() throws FileNotFoundException
692   {
693     PrintWriter pos = new PrintWriter(
694             currentFolder + "/CurrentPosition.txt");
695     pos.println("0");
696     
697     PrintWriter raw = new PrintWriter(currentFolder + RAW);
698     
699     PrintWriter bin = new PrintWriter(currentFolder + BINNED);
700     
701     pos.close();
702     bin.close();
703     raw.close();
704   }
705
706   public void sortIntoClans(String directory) throws IOException
707   {
708     BufferedReader clanFinder = new BufferedReader(new FileReader(FAMILIESTOCLAN));
709     BufferedReader familyReader = new BufferedReader(
710             new FileReader(families));
711     BufferedReader hmmReader = new BufferedReader(new FileReader(hmms));
712     // moveLocationBy(7000, familyReader);
713     // moveLocationBy(7000, clanFinder);
714     // moveLocationBy(7000, hmmReader);
715     HashMap<String, Integer> clanIndexes = new HashMap<>();
716     ArrayList<Integer> familyCounts = new ArrayList<>();
717     int filePos = 0; 
718     int clanCount = 0;
719     String line;
720     line = clanFinder.readLine();
721     
722     while (!"".equals(line) && !" ".equals(line) && line != null)
723     {
724       if (line.contains("HATP") || line.contains("CL0025"))
725       {
726         System.out.println(filePos);
727       }
728      String clanName;
729       boolean inClan = false;
730      while (!(line.indexOf("//") > -1))
731      {
732        
733       if (line.indexOf("#=GF CL") > -1)
734       {
735           inClan = true;
736         Scanner scanner = new Scanner(line);
737         scanner.next();
738         scanner.next();
739         clanName = scanner.next();
740           scanner.close();
741         
742         if (!clanIndexes.containsKey(clanName))
743         {
744           clanIndexes.put(clanName, clanCount);
745             clanCount++;
746             familyCounts.add(0);
747         }
748
749
750           Integer clanI = clanIndexes.get(clanName);
751           String clanPath = directory + "/Clan" + clanI.toString();
752           createFolders(clanPath);
753
754           int index = clanIndexes.get(clanName);
755           exportFile(familyReader,
756                   clanPath + "/Families/Fam" + familyCounts.get(index)
757                           + ".sto",
758                   false);
759           exportFile(hmmReader,
760                   clanPath + "/HMMs/HMM" + familyCounts.get(index) + ".hmm",
761                   false);
762
763           int count = familyCounts.get(index);
764           count++;
765           familyCounts.set(index, count);
766       }
767         line = clanFinder.readLine();
768
769       }
770       if (!inClan)
771       {
772         moveLocationBy(1, familyReader);
773         moveLocationBy(1, hmmReader);
774       }
775       filePos++;
776       // System.out.println(filePos + " files read.");
777       line = clanFinder.readLine();
778
779      }
780     clanFinder.close();
781
782     for (int clan = 0; clan < clanCount; clan++)
783     {
784       PrintWriter writer = new PrintWriter(
785               directory + "/Clan" + clan + "/NumberOfFamilies.txt");
786       int count = familyCounts.get(clan);
787       writer.print(count);
788       writer.close();
789     }
790       
791     }
792
793   public String getFamilies()
794   {
795     return families;
796   }
797
798   public void setFamilies(String families)
799   {
800     this.families = currentFolder + families;
801   }
802
803   public String getHmms()
804   {
805     return hmms;
806   }
807
808   public void setHmms(String hmms)
809   {
810     this.hmms = currentFolder + hmms;
811   }
812     
813   public void alignWithinClan(String exportLocation, String clansLocation)
814           throws IOException, InterruptedException
815   {
816     int alignmentsExported = 0;
817     for (int clan = 0; clan < 604; clan++)
818     {
819
820       int famCount = 0;
821       String clanPath = clansLocation + "/Clan" + clan;
822       int numberOfFamilies;
823       BufferedReader br = new BufferedReader(
824               new FileReader(clanPath + "/NumberOfFamilies.txt"));
825       String line = br.readLine();
826       numberOfFamilies = Integer.parseInt(line);
827       br.close();
828       if (numberOfFamilies == 1)
829       {
830         continue;
831       }
832       final String commandExportLocation = exportLocation + "/Clan" + clan;
833       createFolders(commandExportLocation);
834       for (int family = 0; family < numberOfFamilies; family++)
835       {
836         famCount++;
837         ArrayList<Integer> indexes = new ArrayList<>();
838         for (int i = 0; i < numberOfFamilies; i++)
839         {
840           if (i != family)
841           {
842             indexes.add(i);
843           }
844         }
845
846         int hmmIndex = getRandom(indexes);
847         String famPath = clanPath + "/Families/Fam" + family + ".sto";
848         String hmmPath = clanPath + "/HMMs/HMM" + hmmIndex + ".hmm";
849         String command = "H:/Desktop//hmmer/binaries/hmmalign --mapali "
850                 + clanPath + "/Families/Fam" + hmmIndex + ".sto"
851                 + " --trim ";
852         command += hmmPath + " ";
853         command += famPath;
854         final int familyIndex = family;
855         final Process p = Runtime.getRuntime().exec(command);
856
857         new Thread(new Runnable()
858         {
859           @Override
860           public void run()
861           {
862             BufferedReader input = new BufferedReader(
863                     new InputStreamReader(p.getInputStream()));
864             String line = null;
865
866             try
867             {
868               PrintWriter writer = new PrintWriter(commandExportLocation
869                       + "/Families/Fam" + familyIndex + ".sto");
870               String lastLine = "";
871               boolean dataFound = false;
872               while ((line = input.readLine()) != null)
873               {
874                 if (line.contains("#=GR") && !dataFound)
875                 {
876                   writer.println(lastLine);
877                   dataFound = true;
878                 }
879                 if (line.contains("#") || dataFound || " ".equals(line)
880                         || "".equals(line) || "//".equals(line))
881                 {
882                   writer.println(line);
883                 }
884                 lastLine = line;
885               }
886               writer.close();
887             } catch (IOException e)
888             {
889               e.printStackTrace();
890             }
891           }
892         }).start();
893
894         p.waitFor();
895
896         BufferedReader hmmExporter = new BufferedReader(
897                 new FileReader(hmmPath));
898
899         exportFile(hmmExporter,
900                 commandExportLocation + "/HMMs/HMM" + family + ".hmm",
901                 false);
902
903         alignmentsExported++;
904
905         System.out.println(alignmentsExported + " alignments exported");
906         System.out.println("At clan " + clan);
907
908       }
909       PrintWriter writer = new PrintWriter(
910               commandExportLocation + "/NumberOfFamilies.txt");
911       writer.print(famCount);
912       writer.close();
913     }
914
915   }
916
917   public boolean atEnd(BufferedReader br) throws IOException
918   {
919     boolean end = false;
920     br.mark(80);
921     String line = br.readLine();
922     if ("".equals(line) || line == null)
923     {
924       end = true;
925     }
926     br.reset();
927     return end;
928   }
929
930   public int getRandom(ArrayList<Integer> list)
931   {
932     if (!(list.size() > 0))
933     {
934       System.out.println("Error - size = " + list.size());
935     }
936     int index = generator.nextInt(list.size());
937     int value = list.get(index);
938     list.remove(index);
939     return value;
940   }
941
942   public void createFolders(String clanPath)
943   {
944     File clanFolder = new File(clanPath);
945     if (!clanFolder.exists())
946     {
947       clanFolder.mkdir();
948     }
949
950     File famFolder = new File(clanPath + "/Families");
951     File hmmFolder = new File(clanPath + "/HMMs");
952     if (!famFolder.exists())
953     {
954       famFolder.mkdir();
955       hmmFolder.mkdir();
956     }
957   }
958 }
959
960
961
962