1 package com.github.celldynamics.quimp.filesystem.converter;
2
3 import java.awt.Frame;
4 import java.io.File;
5 import java.io.IOException;
6 import java.nio.file.Path;
7 import java.nio.file.Paths;
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13
14 import javax.swing.JOptionPane;
15
16 import org.slf4j.LoggerFactory;
17
18 import com.github.celldynamics.quimp.BOAState;
19 import com.github.celldynamics.quimp.BOA_;
20 import com.github.celldynamics.quimp.CellStats;
21 import com.github.celldynamics.quimp.FrameStatistics;
22 import com.github.celldynamics.quimp.Nest;
23 import com.github.celldynamics.quimp.Node;
24 import com.github.celldynamics.quimp.Outline;
25 import com.github.celldynamics.quimp.OutlineHandler;
26 import com.github.celldynamics.quimp.PointsList;
27 import com.github.celldynamics.quimp.QParams;
28 import com.github.celldynamics.quimp.QParamsQconf;
29 import com.github.celldynamics.quimp.QuimP;
30 import com.github.celldynamics.quimp.QuimpException;
31 import com.github.celldynamics.quimp.Serializer;
32 import com.github.celldynamics.quimp.Shape;
33 import com.github.celldynamics.quimp.Snake;
34 import com.github.celldynamics.quimp.SnakeHandler;
35 import com.github.celldynamics.quimp.Vert;
36 import com.github.celldynamics.quimp.filesystem.ANAParamCollection;
37 import com.github.celldynamics.quimp.filesystem.DataContainer;
38 import com.github.celldynamics.quimp.filesystem.FileExtensions;
39 import com.github.celldynamics.quimp.filesystem.OutlinesCollection;
40 import com.github.celldynamics.quimp.filesystem.QconfLoader;
41 import com.github.celldynamics.quimp.filesystem.StatsCollection;
42 import com.github.celldynamics.quimp.geom.ExtendedVector2d;
43 import com.github.celldynamics.quimp.plugin.ana.ANAp;
44 import com.github.celldynamics.quimp.plugin.ana.ChannelStat;
45 import com.github.celldynamics.quimp.plugin.qanalysis.FluoMap;
46 import com.github.celldynamics.quimp.plugin.qanalysis.Qp;
47 import com.github.celldynamics.quimp.plugin.qanalysis.STmap;
48 import com.github.celldynamics.quimp.utils.CsvWritter;
49 import com.github.celldynamics.quimp.utils.QuimPArrayUtils;
50
51 import ch.qos.logback.classic.Logger;
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public class FormatConverter {
118 protected static Logger logger =
119 (Logger) LoggerFactory.getLogger(FormatConverter.class.getName());
120 private QconfLoader qcL;
121 private Path path;
122 private Path filename;
123
124
125
126
127 public static final String[] headerEcmmOutline = {
128
129 "charge",
130 "distance",
131 "fluo-ch1_x",
132 "fluo-ch1_y",
133 "fluo-ch1_i",
134 "fluo-ch2_x",
135 "fluo-ch2_y",
136 "fluo-ch2_i",
137 "fluo-ch3_x",
138 "fluo-ch3_y",
139 "fluo-ch3_i",
140 "curvLoc",
141 "curvSmooth",
142 "curvSum",
143 "coord",
144 "gLandCoord",
145 "node_x",
146 "node_y",
147 "normal_x",
148 "normal_y",
149 "tan_x",
150 "tan_y",
151 "position",
152 "frozen"
153 };
154
155
156
157
158
159
160
161 public FormatConverter() {
162 }
163
164
165
166
167
168
169
170 public FormatConverter(File fileToConvert) throws QuimpException {
171 this();
172 attachFile(fileToConvert);
173 }
174
175
176
177
178
179
180
181
182
183
184
185 public void attachFile(File fileToConvert) throws QuimpException {
186 logger.info("Converting file: " + fileToConvert.getName());
187 qcL = new QconfLoader(fileToConvert);
188 path = Paths.get(fileToConvert.getParent());
189 filename = Paths.get(qcL.getQp().getFileName());
190 }
191
192
193
194
195
196
197 public FormatConverter(QconfLoader qcL) {
198 logger.debug("Use provided QconfLoader");
199 this.qcL = qcL;
200 this.path = qcL.getQp().getPathasPath();
201 this.filename = Paths.get(qcL.getQp().getFileName());
202 }
203
204
205
206
207
208
209 public void showConversionCapabilities(Frame frame) {
210
211 JOptionPane.showMessageDialog(frame,
212 "Supported conversions\n"
213 + "paQP->QCONF features:\n"
214 + " [+] paQP->QCONF\n"
215 + " [+] snQP->QCONF\n"
216 + " [+] maQP->QCONF\n"
217 + " [+] stQP->QCONF\n"
218 + "QCONF->paQP features:\n"
219 + " [+] QCONF->paQP\n"
220 + " [+] QCONF->snQP\n"
221 + " [+] QCONF->maQP\n"
222 + " [+] QCONF->stQP\n"
223 + " [-] QCONF->tiffs",
224 "Warning",
225 JOptionPane.WARNING_MESSAGE);
226
227 }
228
229
230
231
232
233
234
235
236
237
238
239 private void generateNewDataFiles() throws QuimpException, IOException {
240 if (qcL.isFileLoaded() == QParams.NEW_QUIMP) {
241 throw new IllegalArgumentException("Can not convert from new format to new");
242 }
243 boolean ecmmRun = false;
244 logger.info("File is in old format, new format will be created");
245
246 DataContaineruimp/filesystem/DataContainer.html#DataContainer">DataContainer dt = new DataContainer();
247 dt.BOAState = new BOAState(qcL.getImage());
248 dt.ECMMState = null;
249 dt.BOAState.nest = new Nest();
250
251 ArrayList<STmap> maps = new ArrayList<>();
252
253
254 int last = filename.toString().lastIndexOf('_');
255 if (last < 0) {
256 throw new QuimpException(
257 "Input file name must be in format name_XX.paQP, where XX is cell number.");
258 }
259
260
261 try {
262 int numofpaqp;
263 numofpaqp = Integer
264 .parseInt(filename.toString().substring(last + 1, filename.toString().length()));
265 if (numofpaqp != 0) {
266 throw new QuimpException("Selected paQP file is not first (not a _0.paQP file).");
267 }
268 } catch (NumberFormatException e) {
269 throw new QuimpException("Number can not be found in file paQP name. "
270 + "Check if file name is in format name_XX.paQP, where XX is cell number.");
271 }
272
273 String orginal = filename.toString().substring(0, last);
274
275 int i;
276
277 i = 0;
278 File filetoload = new File("");
279 OutlineHandler oh;
280 STmap stMap;
281 ANAParamCollectionlesystem/ANAParamCollection.html#ANAParamCollection">ANAParamCollection anaP = new ANAParamCollection();
282 try {
283 do {
284
285 filetoload =
286 Paths.get(qcL.getQp().getPath(), orginal + "_" + i + FileExtensions.configFileExt)
287 .toFile();
288 logger.info("Attempting to process " + filetoload.getName());
289 if (!filetoload.exists()) {
290 logger.info("File " + filetoload.toString() + " does not exist. Finishing conversion.");
291 break;
292 }
293
294 if (i != 0) {
295 qcL = new QconfLoader(filetoload);
296 } else {
297
298 dt.BOAState.loadParams(qcL.getQp());
299 dt.BOAState.boap.setImageFrameInterval(qcL.getQp().getFrameInterval());
300 dt.BOAState.boap.setImageScale(qcL.getQp().getImageScale());
301 }
302 logger.info(toString());
303
304 logger.info("... Reading snakes");
305
306 ecmmRun = qcL.getQp().verifyEcmminpsnQP();
307 BOA_.qState = dt.BOAState;
308 oh = new OutlineHandler(qcL.getQp());
309 if (ecmmRun) {
310 if (dt.ECMMState == null) {
311 dt.ECMMState = new OutlinesCollection();
312 }
313 dt.ECMMState.oHs.add(oh);
314 } else {
315 logger.info("... Reading snakes - no ECMM data");
316 }
317 dt.BOAState.nest.addOutlinehandler(oh);
318
319
320 stMap = new STmap();
321 int readMap = 0;
322 try {
323 logger.info("\tReading " + qcL.getQp().getMotilityFile().getName());
324 stMap.setMotMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getMotilityFile()));
325 readMap++;
326 } catch (IOException e) {
327 logger.info(e.getMessage());
328 logger.debug(e.getMessage(), e);
329 }
330 try {
331 logger.info("\tReading " + qcL.getQp().getConvexFile().getName());
332 stMap.setConvMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getConvexFile()));
333 readMap++;
334 } catch (IOException e) {
335 logger.info(e.getMessage());
336 logger.debug(e.getMessage(), e);
337 }
338 try {
339 logger.info("\tReading " + qcL.getQp().getCoordFile().getName());
340 stMap.setCoordMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getCoordFile()));
341 readMap++;
342 } catch (IOException e) {
343 logger.info(e.getMessage());
344 logger.debug(e.getMessage(), e);
345 }
346 try {
347 logger.info("\tReading " + qcL.getQp().getOriginFile().getName());
348 stMap.setOriginMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getOriginFile()));
349 readMap++;
350 } catch (IOException e) {
351 logger.debug(e.getMessage(), e);
352 logger.info(e.getMessage());
353 }
354 try {
355 logger.info("\tReading " + qcL.getQp().getxmapFile().getName());
356 stMap.setxMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getxmapFile()));
357 readMap++;
358 } catch (IOException e) {
359 logger.info(e.getMessage());
360 logger.debug(e.getMessage(), e);
361 }
362 try {
363 logger.info("\tReading " + qcL.getQp().getymapFile().getName());
364 stMap.setyMap(QuimPArrayUtils.file2Array(",", qcL.getQp().getymapFile()));
365 readMap++;
366 } catch (IOException e) {
367 logger.info(e.getMessage());
368 logger.debug(e.getMessage(), e);
369 }
370
371 if (readMap >= 1 && readMap < 6) {
372 logger.warn("It seems that you have missing maps. Perhaps your dataset is incomplete. "
373 + "This may lead to invalid QCONF file.");
374 }
375
376
377 int channel = 1;
378 int p = 0;
379 int t = 0;
380 for (File ff : qcL.getQp().getFluFiles()) {
381
382
383
384 if (ff.exists()) {
385 double[][] tmpFluMap = QuimPArrayUtils.file2Array(",", ff);
386 t = tmpFluMap.length;
387 p = tmpFluMap[0].length;
388
389 if (stMap.getT() == 0) {
390 logger.warn("It seems that you have fluorosence map but other maps are missing."
391 + " Perhaps your dataset is incomplete. "
392 + "This may lead to invalid QCONF file.");
393 }
394 break;
395 }
396 }
397
398
399 for (File ff : qcL.getQp().getFluFiles()) {
400
401 FluoMapics/quimp/plugin/qanalysis/FluoMap.html#FluoMap">FluoMap chm = new FluoMap(t, p, channel);
402 if (ff.exists()) {
403 logger.info("\tReading " + ff.getName());
404 chm.setMap(QuimPArrayUtils.file2Array(",", ff));
405 } else {
406 chm.setEnabled(false);
407 logger.info("File " + ff.toString() + " not found.");
408 }
409 stMap.fluoMaps[channel - 1] = chm;
410 channel++;
411 }
412
413 if (stMap.getT() != 0 || t != 0) {
414 maps.add(stMap);
415 }
416
417 logger.info("\tFilling ANA");
418 ANApcs/quimp/plugin/ana/ANAp.html#ANAp">ANAp anapTmp = new ANAp();
419 anapTmp.scale = qcL.getQp().getImageScale();
420 anapTmp.setCortextWidthScale(qcL.getQp().cortexWidth);
421 anapTmp.fluTiffs = qcL.getQp().fluTiffs;
422 anaP.aS.add(anapTmp);
423
424 i++;
425 } while (true);
426
427
428
429 logger.info("\tReading stats");
430
431 StatFileParsermp/filesystem/converter/StatFileParser.html#StatFileParser">StatFileParser obj = new StatFileParser(Paths.get(qcL.getQp().getPath(), orginal).toString());
432 List<Path> statFiles = obj.getAllFiles();
433
434 if (i != statFiles.size()) {
435 logger.warn("It seems that number of stQP files is different than number of paQP files."
436 + " Perhaps your dataset is incomplete. This may lead to invalid QCONF file.");
437 }
438 ArrayList<CellStats> stats = obj.importStQp();
439 dt.Stats = new StatsCollection();
440 dt.Stats.setStatCollection(stats);
441
442 } catch (Exception e) {
443 throw new QuimpException(
444 "File " + filetoload.toString() + " can not be processed: " + e.getMessage(), e);
445 }
446
447 int count = 0;
448 for (STmap tmp : maps) {
449 if (tmp.getT() == 0) {
450 count++;
451 } else {
452 count--;
453 }
454 }
455 if (Math.abs(count) != maps.size()) {
456 logger.warn("It seems that some paQP cases have missing maps."
457 + " Perhaps your dataset is incomplete. This may lead to invalid QCONF file.");
458 }
459
460 if (!maps.isEmpty()) {
461 dt.QState = maps.toArray(new STmap[0]);
462 } else {
463 dt.QState = null;
464 }
465 if (ecmmRun) {
466 dt.ANAState = anaP;
467 } else {
468 dt.ANAState = null;
469 }
470
471 Serializer<DataContainer> n;
472 n = new Serializer<>(dt, QuimP.TOOL_VERSION);
473 n.setPretty();
474 n.save(path + File.separator + orginal + FileExtensions.newConfigFileExt);
475 n = null;
476 }
477
478
479
480
481
482
483
484
485
486
487 private void generateOldDataFiles() throws IOException, QuimpException {
488 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
489 throw new IllegalArgumentException("Can not convert from old format to old");
490 }
491 logger.info("File is in new format, old format will be created");
492 logger.info(toString());
493 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
494 if (dt.getEcmmState() == null) {
495 logger.warn("ECMM analysis is not present in QCONF");
496 generatepaQP();
497 } else {
498 generatesnQP();
499 }
500 if (qcL.isStatsPresent()) {
501 saveStats();
502 } else {
503 logger.warn("Statistics are not present in QCONF");
504 }
505 if (qcL.isQPresent()) {
506 saveMaps(STmap.ALLMAPS);
507 } else {
508 logger.warn("Q analysis is not present in QCONF");
509 }
510 }
511
512
513
514
515
516
517
518
519
520
521
522
523 public void saveMaps(int maps) throws QuimpException {
524 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
525 throw new IllegalArgumentException("New format required.");
526 }
527 int activeHandler = 0;
528
529 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
530 dt.BOAState.boap.setOutputFileCore(path + File.separator + filename.toString());
531 String name = STmap.LOGGER.getName();
532 STmap.LOGGER = logger;
533 Qpamics/quimp/plugin/qanalysis/Qp.html#Qp">Qp params = new Qp();
534 try {
535 for (STmap stmap : qcL.getQ()) {
536 ((QParamsQconf) qcL.getQp()).setActiveHandler(activeHandler++);
537 stmap.setParams(params);
538 params.setup(qcL.getQp());
539 stmap.saveMaps(maps);
540 }
541 } finally {
542 STmap.LOGGER = LoggerFactory.getLogger(name);
543 }
544 }
545
546
547
548
549
550
551
552
553 public void saveBoaCentroids() throws QuimpException {
554 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
555 throw new IllegalArgumentException("New format required.");
556 }
557 int activeHandler = 0;
558 CsvWritter csv = null;
559 for (SnakeHandler sh : qcL.getBOA().nest.getHandlers()) {
560 try {
561 csv = new CsvWritter(getFeatureFileName("boacentroid", activeHandler, ".csv"), "#frame",
562 "centroid_x", "centroid_y");
563 logger.info("\tSaved Boa centroids at: " + csv.getPath().getFileName());
564 int sf = sh.getStartFrame();
565 int ef = sh.getEndFrame();
566 for (int f = sf; f <= ef; f++) {
567 Snake snake = sh.getStoredSnake(f);
568 ExtendedVector2d centroid = snake.getCentroid();
569 csv.writeLine((double) f, centroid.x, centroid.y);
570 }
571 } catch (IOException e) {
572 logger.error("Can not write file");
573 } finally {
574 activeHandler++;
575 if (csv != null) {
576 csv.close();
577 }
578 }
579 }
580
581 }
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596 public void saveBoaSnakes(boolean separateFiles) throws QuimpException {
597 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
598 throw new IllegalArgumentException("New format required.");
599 }
600
601 final String[] params = {
602 "vel_x",
603 "vel_y",
604 "F-total_x",
605 "F-total_y",
606 "node_x",
607 "node_y",
608 "normal_x",
609 "normal_y",
610 "tan_x",
611 "tan_y",
612 "position",
613 "frozen"};
614
615 CsvWritter csv = null;
616 int activeHandler = 0;
617 for (SnakeHandler sh : qcL.getBOA().nest.getHandlers()) {
618 int sf = sh.getStartFrame();
619 int ef = sh.getEndFrame();
620 try {
621 for (int f = sf; f <= ef; f++) {
622 Snake snake = sh.getStoredSnake(f);
623 if (separateFiles == true) {
624 csv = new CsvWritter(getFeatureFileName("snake-frame" + f, activeHandler, ".csv"),
625 params);
626 } else if (f == sf) {
627 csv = new CsvWritter(getFeatureFileName("snake", activeHandler, ".csv"), params);
628
629 }
630 if (separateFiles == false) {
631 csv.writeLine("#frame " + f);
632 }
633 logger.info("\tSaved snakes at: " + csv.getPath().getFileName());
634 Iterator<Node> it = snake.iterator();
635 while (it.hasNext()) {
636 Node n = it.next();
637
638 csv.writeLine(
639 n.getVel().x,
640 n.getVel().y,
641 n.getF_total().x,
642 n.getF_total().y,
643 n.getPoint().x,
644 n.getPoint().y,
645 n.getNormal().x,
646 n.getNormal().y,
647 n.getTangent().x,
648 n.getTangent().y,
649 n.getPosition(),
650 n.isFrozen() ? 1.0 : 0.0);
651
652 }
653 if (separateFiles == true) {
654 csv.close();
655 }
656 }
657 } catch (IOException e) {
658 logger.error("Can not write file");
659 } finally {
660 activeHandler++;
661 if (csv != null) {
662 csv.close();
663 }
664 }
665 }
666 }
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681 public void saveEcmmOutlines(boolean separateFiles) throws QuimpException {
682 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
683 throw new IllegalArgumentException("New format required.");
684 }
685 CsvWritter csv = null;
686 int activeHandler = 0;
687 for (OutlineHandler oh : qcL.getEcmm().oHs) {
688 int sf = oh.getStartFrame();
689 int ef = oh.getEndFrame();
690 try {
691 for (int f = sf; f <= ef; f++) {
692 Outline outline = oh.getStoredOutline(f);
693 if (separateFiles == true) {
694 csv = new CsvWritter(getFeatureFileName("outline-frame" + f, activeHandler, ".csv"),
695 headerEcmmOutline);
696 } else if (f == sf) {
697 csv = new CsvWritter(getFeatureFileName("outline", activeHandler, ".csv"),
698 headerEcmmOutline);
699 }
700 if (separateFiles == false) {
701 csv.writeLine("#frame " + f);
702 }
703 saveOutline(outline, csv);
704 if (separateFiles == true) {
705 csv.close();
706 }
707 }
708 } catch (IOException e) {
709 logger.error("Can not write file");
710 } finally {
711 activeHandler++;
712 if (csv != null) {
713 csv.close();
714 }
715 }
716 }
717 }
718
719
720
721
722
723
724
725 public static void saveOutline(Outline outline, CsvWritter csv) {
726 logger.info("\tSaved outlines at: " + csv.getPath().getFileName());
727 Iterator<Vert> it = outline.iterator();
728 while (it.hasNext()) {
729 Vert n = it.next();
730
731 csv.writeLine(
732 n.charge,
733 n.distance,
734 n.fluores[0].x,
735 n.fluores[0].y,
736 n.fluores[0].intensity,
737 n.fluores[1].x,
738 n.fluores[1].y,
739 n.fluores[1].intensity,
740 n.fluores[2].x,
741 n.fluores[2].y,
742 n.fluores[2].intensity,
743 n.getCurvatureLocal(),
744 n.curvatureSmoothed,
745 n.curvatureSum,
746 n.coord,
747 n.gLandCoord,
748 n.getPoint().x,
749 n.getPoint().y,
750 n.getNormal().x,
751 n.getNormal().y,
752 n.getTangent().x,
753 n.getTangent().y,
754 n.getPosition(),
755 n.isFrozen() ? 1.0 : 0.0);
756
757 }
758 }
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773 public void saveStatFluores() throws QuimpException {
774 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
775 throw new IllegalArgumentException("New format required.");
776 }
777
778 final String[] params = {
779 "#frame",
780 "innerAreaCh1",
781 "totalFluorCh1",
782 "cortexWidthCh1",
783 "meanFluorCh1",
784 "meanInnerFluorCh1",
785 "totalInnerFluorCh1",
786 "cortexAreaCh1",
787 "totalCorFluoCh1",
788 "meanCorFluoCh1",
789 "percCortexFluoCh1",
790 "innerAreaCh2",
791 "totalFluorCh2",
792 "cortexWidthCh2",
793 "meanFluorCh2",
794 "meanInnerFluorCh2",
795 "totalInnerFluorCh2",
796 "cortexAreaCh2",
797 "totalCorFluoCh2",
798 "meanCorFluoCh2",
799 "percCortexFluoCh2",
800 "innerAreaCh3",
801 "totalFluorCh3",
802 "cortexWidthCh3",
803 "meanFluorCh3",
804 "meanInnerFluorCh3",
805 "totalInnerFluorCh3",
806 "cortexAreaCh3",
807 "totalCorFluoCh3",
808 "meanCorFluoCh3",
809 "percCortexFluoCh3"
810 };
811
812 CsvWritter csv = null;
813 int activeHandler = 0;
814 StatsCollection st = qcL.getStats();
815 for (CellStats cs : st.getStatCollection()) {
816 try {
817 csv = new CsvWritter(getFeatureFileName("fluostats", activeHandler, ".csv"), params);
818 logger.info("\tSaved fluorosence stats at: " + csv.getPath().getFileName());
819 for (FrameStatistics fs : cs.getFramestat()) {
820 ChannelStat[] ch = fs.channels;
821
822 csv.writeLine(
823 (double)fs.frame,
824 ch[0].innerArea,
825 ch[0].totalFluor,
826 ch[0].cortexWidth,
827 ch[0].meanFluor,
828 ch[0].meanInnerFluor,
829 ch[0].totalInnerFluor,
830 ch[0].cortexArea,
831 ch[0].totalCorFluo,
832 ch[0].meanCorFluo,
833 ch[0].percCortexFluo,
834 ch[1].innerArea,
835 ch[1].totalFluor,
836 ch[1].cortexWidth,
837 ch[1].meanFluor,
838 ch[1].meanInnerFluor,
839 ch[1].totalInnerFluor,
840 ch[1].cortexArea,
841 ch[1].totalCorFluo,
842 ch[1].meanCorFluo,
843 ch[1].percCortexFluo,
844 ch[2].innerArea,
845 ch[2].totalFluor,
846 ch[2].cortexWidth,
847 ch[2].meanFluor,
848 ch[2].meanInnerFluor,
849 ch[2].totalInnerFluor,
850 ch[2].cortexArea,
851 ch[2].totalCorFluo,
852 ch[2].meanCorFluo,
853 ch[2].percCortexFluo
854 );
855
856 }
857 } catch (IOException e) {
858 logger.error("Can not write file");
859 } finally {
860 activeHandler++;
861 if (csv != null) {
862 csv.close();
863 }
864 }
865 }
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881 public void saveStatGeom() throws QuimpException {
882 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
883 throw new IllegalArgumentException("New format required.");
884 }
885
886 final String[] params = {
887 "#frame",
888 "area",
889 "elongation",
890 "circularity",
891 "perimiter",
892 "displacement",
893 "dist",
894 "persistance",
895 "speed",
896 "persistanceToSource",
897 "dispersion",
898 "extension",
899 "centroid_x",
900 "centroid_y"
901 };
902
903 CsvWritter csv = null;
904 int activeHandler = 0;
905 StatsCollection st = qcL.getStats();
906 for (CellStats cs : st.getStatCollection()) {
907 try {
908 csv = new CsvWritter(getFeatureFileName("geomstats", activeHandler, ".csv"), params);
909 logger.info("\tSaved geometrical stats at: " + csv.getPath().getFileName());
910 for (FrameStatistics fs : cs.getFramestat()) {
911
912 csv.writeLine(
913 (double)fs.frame,
914 fs.area,
915 fs.elongation,
916 fs.circularity,
917 fs.perimiter,
918 fs.displacement,
919 fs.dist,
920 fs.persistance,
921 fs.speed,
922 fs.persistanceToSource,
923 fs.dispersion,
924 fs.extension,
925 fs.centroid.x,
926 fs.centroid.y
927 );
928
929 }
930 } catch (IOException e) {
931 logger.error("Can not write file");
932 } finally {
933 activeHandler++;
934 if (csv != null) {
935 csv.close();
936 }
937 }
938 }
939 }
940
941
942
943
944
945
946
947
948 public void saveEcmmCentroids() throws QuimpException {
949 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
950 throw new IllegalArgumentException("New format required.");
951 }
952 int activeHandler = 0;
953 CsvWritter csv = null;
954 for (OutlineHandler oh : qcL.getEcmm().oHs) {
955 try {
956 csv = new CsvWritter(getFeatureFileName("ecmmcentroid", activeHandler, ".csv"), "#frame",
957 "centroid_x", "centroid_y");
958 logger.info("\tSaved ecmm centroids at: " + csv.getPath().getFileName());
959 int sf = oh.getStartFrame();
960 int ef = oh.getEndFrame();
961 for (int f = sf; f <= ef; f++) {
962 Outline outline = oh.getStoredOutline(f);
963 ExtendedVector2d centroid = outline.getCentroid();
964 csv.writeLine((double) f, centroid.x, centroid.y);
965 }
966 } catch (IOException e) {
967 logger.error("Can not write file");
968 } finally {
969 activeHandler++;
970 if (csv != null) {
971 csv.close();
972 }
973 }
974 }
975
976 }
977
978
979
980
981
982
983
984
985 public void saveStats() throws QuimpException {
986 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
987 throw new IllegalArgumentException("Can not convert from old format to old");
988 }
989 int activeHandler = 0;
990 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
991 Iterator<CellStats> csI = qcL.getStats().getStatCollection().iterator();
992 do {
993 Path p = getFeatureFileName("", activeHandler, FileExtensions.statsFileExt);
994 ((QParamsQconf) qcL.getQp()).setActiveHandler(activeHandler);
995 CellStats cs = csI.next();
996 try {
997 FrameStatistics.write(cs.getFramestat().toArray(new FrameStatistics[0]),
998 ((QParamsQconf) qcL.getQp()).getStatsQP(), dt.BOAState.boap.getImageScale(),
999 dt.BOAState.boap.getImageFrameInterval());
1000 logger.info("\tSaved stats at: " + p.getFileName());
1001 } catch (IOException e) {
1002 logger.error("Can not write file");
1003 } finally {
1004 activeHandler++;
1005 }
1006 } while (csI.hasNext());
1007
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019 Path getFeatureFileName(String featName, int cellNo, String ext) {
1020 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
1021 dt.BOAState.boap.setOutputFileCore(path + File.separator + filename.toString());
1022 String fi = dt.BOAState.boap.getOutputFileCore().toPath().toString();
1023 fi = fi + "_" + cellNo + "_" + featName + ext;
1024 return Paths.get(fi);
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035 private void generatepaQP() throws IOException {
1036 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
1037 throw new IllegalArgumentException("Can not convert from old format to old");
1038 }
1039 logger.info("\tCreating configuration files");
1040
1041 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
1042 dt.getBOAState().boap.setOutputFileCore(path + File.separator + filename.toString());
1043 logger.info("\tCreating snake files");
1044 dt.BOAState.nest.writeSnakes();
1045 }
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 private void generatesnQP() throws IOException {
1056 if (qcL.isFileLoaded() == QParams.QUIMP_11) {
1057 throw new IllegalArgumentException("Can not convert from old format to old");
1058 }
1059 int activeHandler = 0;
1060
1061 DataContainer dt = ((QParamsQconf) qcL.getQp()).getLoadedDataContainer();
1062 dt.BOAState.boap.setOutputFileCore(path + File.separator + filename.toString());
1063 Iterator<OutlineHandler> ohi = dt.getEcmmState().oHs.iterator();
1064 do {
1065 logger.info("\tCreating snake file " + activeHandler);
1066 ((QParamsQconf) qcL.getQp()).setActiveHandler(activeHandler);
1067 OutlineHandler oh = ohi.next();
1068 oh.writeOutlines(((QParamsQconf) qcL.getQp()).getSnakeQP(), true);
1069 logger.info("\tCreating parameter file " + activeHandler);
1070 ((QParamsQconf) qcL.getQp()).writeOldParams();
1071 activeHandler++;
1072 } while (ohi.hasNext());
1073
1074 }
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 public void doConversion() throws QuimpException {
1087 try {
1088 switch (qcL.isFileLoaded()) {
1089 case QParams.NEW_QUIMP:
1090 generateOldDataFiles();
1091 break;
1092 case QParams.QUIMP_11:
1093 Map<Integer, String> ret = QconfLoader.validatePaqp(
1094 qcL.getQp().getPathasPath().resolve(qcL.getQp().getParamFile().toPath()));
1095 if (!ret.isEmpty()) {
1096 logger.warn("Sanity check returned the following warnings for paQP structure:");
1097 ret.values().stream().forEach(i -> Arrays.asList(i.split(QconfLoader.SEPARATOR))
1098 .stream().forEach(j -> logger.warn(j)));
1099 logger.warn("FormatConverter will try to convert such file but it may"
1100 + " lead to invalid QCONF file");
1101 }
1102 generateNewDataFiles();
1103 break;
1104 default:
1105 throw new IllegalArgumentException(
1106 "QconfLoader returned unknown version of QuimP or error: " + qcL.isFileLoaded());
1107 }
1108 } catch (IOException qe) {
1109 throw new QuimpException(qe);
1110 }
1111 }
1112
1113
1114
1115
1116
1117
1118
1119 public int isFileLoaded() {
1120 if (qcL == null) {
1121 return QconfLoader.QCONF_INVALID;
1122 } else {
1123 return qcL.isFileLoaded();
1124 }
1125 }
1126
1127
1128
1129
1130
1131
1132 @Override
1133 public String toString() {
1134 String ret = "";
1135 switch (qcL.isFileLoaded()) {
1136 case QParams.NEW_QUIMP:
1137 ret = ret.concat("Experiment date: ")
1138 .concat(((QParamsQconf) qcL.getQp()).getFileVersion().getBuildstamp()).concat("\n");
1139 ret = ret.concat("File version: ")
1140 .concat(((QParamsQconf) qcL.getQp()).getFileVersion().getVersion()).concat("\n");
1141 ret = ret.concat("Is BOA analysis present? ").concat(" -- ")
1142 .concat(Boolean.toString(qcL.isBOAPresent())).concat("\n");
1143 ret = ret.concat("Is ECMM analysis present? ").concat(" -- ")
1144 .concat(Boolean.toString(qcL.isECMMPresent())).concat("\n");
1145 ret = ret.concat("Is ANA analysis present? ").concat(" -- ")
1146 .concat(Boolean.toString(qcL.isANAPresent())).concat("\n");
1147 ret = ret.concat("Is Q analysis present? ").concat(" -- ")
1148 .concat(Boolean.toString(qcL.isQPresent())).concat("\n");
1149 ret = ret.concat("Are stats present? ").concat(" -- ")
1150 .concat(Boolean.toString(qcL.isStatsPresent())).concat("\n");
1151 return ret;
1152 case QParams.QUIMP_11:
1153 ret = ret.concat(qcL.getQp().getFileName()).concat("\n");
1154 ret = ret.concat("Is file ").concat(qcL.getQp().getParamFile().getName())
1155 .concat(" present? ").concat(" -- ")
1156 .concat(Boolean.toString(qcL.getQp().getParamFile().exists())).concat("\n");
1157 ret = ret.concat("Is file ").concat(qcL.getQp().getSnakeQP().getName()).concat(" present? ")
1158 .concat(" -- ").concat(Boolean.toString(qcL.getQp().getSnakeQP().exists()))
1159 .concat("\n");
1160 ret = ret.concat("Is file ").concat(qcL.getQp().getStatsQP().getName()).concat(" present? ")
1161 .concat(" -- ").concat(Boolean.toString(qcL.getQp().getStatsQP().exists()))
1162 .concat("\n");
1163 ret = ret.concat("Is file ").concat(qcL.getQp().getMotilityFile().getName())
1164 .concat(" present? ").concat(" -- ")
1165 .concat(Boolean.toString(qcL.getQp().getMotilityFile().exists())).concat("\n");
1166 ret = ret.concat("Is file ").concat(qcL.getQp().getConvexFile().getName())
1167 .concat(" present? ").concat(" -- ")
1168 .concat(Boolean.toString(qcL.getQp().getConvexFile().exists())).concat("\n");
1169 ret = ret.concat("Is file ").concat(qcL.getQp().getCoordFile().getName())
1170 .concat(" present? ").concat(" -- ")
1171 .concat(Boolean.toString(qcL.getQp().getCoordFile().exists())).concat("\n");
1172 ret = ret.concat("Is file ").concat(qcL.getQp().getOriginFile().getName())
1173 .concat(" present? ").concat(" -- ")
1174 .concat(Boolean.toString(qcL.getQp().getOriginFile().exists())).concat("\n");
1175 ret = ret.concat("Is file ").concat(qcL.getQp().getxmapFile().getName())
1176 .concat(" present? ").concat(" -- ")
1177 .concat(Boolean.toString(qcL.getQp().getxmapFile().exists())).concat("\n");
1178 ret = ret.concat("Is file ").concat(qcL.getQp().getymapFile().getName())
1179 .concat(" present? ").concat(" -- ")
1180 .concat(Boolean.toString(qcL.getQp().getymapFile().exists())).concat("\n");
1181 File[] tmpf = qcL.getQp().getFluFiles();
1182 for (File f : tmpf) {
1183 ret = ret.concat("Is file ").concat(f.getName()).concat(" present? ").concat(" -- ")
1184 .concat(Boolean.toString(f.exists())).concat("\n");
1185 }
1186 return ret;
1187 case QParams.OLD_QUIMP:
1188 ret = "toString is not supported for this format";
1189 return ret;
1190 default:
1191 return "No file loaded or file damaged";
1192 }
1193 }
1194
1195 }