Skip to content

Commit 67123eb

Browse files
gmgunterGitHub Enterprise
authored andcommitted
Convert SNAPHU logging to pyre::journal (#1001)
* Convert SNAPHU logging to use pyre::journal * Remove 'verbose' option that no longer has any effect * Remove trailing newline characters from error messages * Change SNAPHU debug output to info w/ increased detail level * Assign verbose status messages to a unique channel * Use named variables instead of magic numbers Fix some output that was accidentally streamed to the "verbose" channel instead of the "status" channel * Replace newline characters with `pyre::journal::newline` ... in order to preserve formatting * Use a single space after a period * Update behavior of InSAR param "phase_unwrap.snaphu.verbose" Rather than passing this parameter to `snaphu.unwrap()` (which is no longer supported), instead increase the detail level of "isce3.unwrap.snaphu" channels to produce more verbose output. * Convert new log messages from #995
1 parent 55f1c09 commit 67123eb

File tree

10 files changed

+582
-353
lines changed

10 files changed

+582
-353
lines changed

cxx/isce3/unwrap/snaphu/snaphu.cpp

Lines changed: 90 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <cstdlib>
1212
#include <csignal>
13+
#include <iomanip>
1314
#include <unistd.h>
1415
#include <sys/wait.h>
1516

@@ -26,13 +27,6 @@ namespace isce3::unwrap {
2627
char dumpresults_global = FALSE;
2728
char requestedstop_global = FALSE;
2829

29-
/* ouput stream pointers */
30-
/* sp0=error messages, sp1=status output, sp2=verbose, sp3=verbose counter */
31-
FILE *sp0 = NULL;
32-
FILE *sp1 = NULL;
33-
FILE *sp2 = NULL;
34-
FILE *sp3 = NULL;
35-
3630
/* node pointer for marking arc not on tree in apex array */
3731
/* this should be treated as a constant */
3832
nodeT NONTREEARC[1]={};
@@ -66,15 +60,15 @@ void snaphuUnwrap(const std::string& configfile){
6660
double cputimestart;
6761
long linelen, nlines;
6862

63+
auto info=pyre::journal::info_t("isce3.unwrap.snaphu");
6964

7065
/* get current wall clock and CPU time */
7166
StartTimers(&tstart,&cputimestart);
7267

73-
/* set output stream pointers (may be reset after inputs parsed) */
74-
SetStreamPointers();
75-
7668
/* print greeting */
77-
fprintf(sp1,"\n%s v%s\n",PROGRAMNAME,VERSION);
69+
info << pyre::journal::at(__HERE__)
70+
<< PROGRAMNAME << " v" << VERSION
71+
<< pyre::journal::endl;
7872

7973
/* set default parameters */
8074
SetDefaults(infiles,outfiles,params);
@@ -83,9 +77,6 @@ void snaphuUnwrap(const std::string& configfile){
8377
/* read input config file */
8478
ReadConfigFile(configfile.data(),infiles,outfiles,&linelen,params);
8579

86-
/* set verbose output if specified */
87-
SetVerboseOut(params);
88-
8980
/* set names of dump files if necessary */
9081
SetDumpAll(outfiles,params);
9182

@@ -102,7 +93,9 @@ void snaphuUnwrap(const std::string& configfile){
10293
Unwrap(infiles,outfiles,params,linelen,nlines);
10394

10495
/* finish up */
105-
fprintf(sp1,"Program %s done\n",PROGRAMNAME);
96+
info << pyre::journal::at(__HERE__)
97+
<< "Program " << PROGRAMNAME << " done"
98+
<< pyre::journal::endl;
10699
DisplayElapsedTime(tstart,cputimestart);
107100

108101
} /* end of snaphuUnwrap() */
@@ -178,6 +171,8 @@ int Unwrap(infileT *infiles, outfileT *outfiles, paramT *params,
178171
double tilecputimestart;
179172
time_t tiletstart;
180173

174+
auto info=pyre::journal::info_t("isce3.unwrap.snaphu");
175+
181176
/* see if we need to do single-tile reoptimization and set up if so */
182177
if(params->onetilereopt){
183178
noptiter=2;
@@ -203,7 +198,9 @@ int Unwrap(infileT *infiles, outfileT *outfiles, paramT *params,
203198
SetTileInitOutfile(iteroutfiles->outfile,iterparams->parentpid);
204199
StrNCopy(tileinitfile,iteroutfiles->outfile,MAXSTRLEN);
205200
iteroutfiles->outfileformat=TILEINITFILEFORMAT;
206-
fprintf(sp1,"Starting first-round tile-mode unwrapping\n");
201+
info << pyre::journal::at(__HERE__)
202+
<< "Starting first-round tile-mode unwrapping"
203+
<< pyre::journal::endl;
207204

208205
}
209206

@@ -218,7 +215,9 @@ int Unwrap(infileT *infiles, outfileT *outfiles, paramT *params,
218215
iterparams->ntilecol=1;
219216
iterparams->rowovrlp=0;
220217
iterparams->colovrlp=0;
221-
fprintf(sp1,"Starting second-round single-tile unwrapping\n");
218+
info << pyre::journal::at(__HERE__)
219+
<< "Starting second-round single-tile unwrapping"
220+
<< pyre::journal::endl;
222221

223222
}else{
224223
throw isce3::except::RuntimeError(ISCE_SRCINFO(),
@@ -315,17 +314,15 @@ int Unwrap(infileT *infiles, outfileT *outfiles, paramT *params,
315314

316315
/* set up tile parameters */
317316
pid=getpid();
318-
fprintf(sp1,
319-
"Unwrapping tile at row %ld, column %ld (pid %ld)\n",
320-
nexttilerow,nexttilecol,(long )pid);
317+
info << pyre::journal::at(__HERE__)
318+
<< "Unwrapping tile at row " << nexttilerow
319+
<< ", column " << nexttilecol << " (pid "
320+
<< ((long )pid) << ")"
321+
<< pyre::journal::endl;
321322
SetupTile(nlines,linelen,iterparams,tileparams,
322323
iteroutfiles,tileoutfiles,
323324
nexttilerow,nexttilecol);
324325

325-
/* reset stream pointers for logging */
326-
ChildResetStreamPointers(pid,nexttilerow,nexttilecol,
327-
iterparams);
328-
329326
/* unwrap the tile */
330327
UnwrapTile(iterinfiles,tileoutfiles,iterparams,tileparams,
331328
nlines,linelen,tag);
@@ -390,8 +387,10 @@ int Unwrap(infileT *infiles, outfileT *outfiles, paramT *params,
390387
if(dotilemask(nexttilerow,nexttilecol)){
391388

392389
/* set up tile parameters */
393-
fprintf(sp1,"Unwrapping tile at row %ld, column %ld\n",
394-
nexttilerow,nexttilecol);
390+
info << pyre::journal::at(__HERE__)
391+
<< "Unwrapping tile at row " << nexttilerow
392+
<< ", column " << nexttilecol
393+
<< pyre::journal::endl;
395394
SetupTile(nlines,linelen,iterparams,tileparams,
396395
iteroutfiles,tileoutfiles,
397396
nexttilerow,nexttilecol);
@@ -460,6 +459,11 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
460459
using Cost=typename CostTag::Cost;
461460
Array2D<Cost> costs;
462461

462+
auto info=pyre::journal::info_t("isce3.unwrap.snaphu");
463+
constexpr int output_detail_level=2;
464+
auto verbose=pyre::journal::info_t("isce3.unwrap.snaphu",output_detail_level);
465+
auto status=pyre::journal::info_t("isce3.unwrap.snaphu.status",output_detail_level);
466+
463467
/* get size of tile */
464468
nrow=tileparams->nrow;
465469
ncol=tileparams->ncol;
@@ -494,10 +498,14 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
494498
/* if in quantify-only mode, evaluate cost of unwrapped input then return */
495499
if(params->eval){
496500
mostflow=Short2DRowColAbsMax(flows,nrow,ncol);
497-
fprintf(sp1,"Maximum flow on network: %ld\n",mostflow);
501+
info << pyre::journal::at(__HERE__)
502+
<< "Maximum flow on network: " << mostflow
503+
<< pyre::journal::endl;
498504
Array1D<int> dummy;
499505
totalcost=EvaluateTotalCost(costs,flows,nrow,ncol,dummy,params,tag);
500-
fprintf(sp1,"Total solution cost: %.9g\n",(double )totalcost);
506+
info << pyre::journal::at(__HERE__) << "Total solution cost: "
507+
<< std::fixed << std::setprecision(9) << ((double )totalcost)
508+
<< pyre::journal::endl;
501509
return(1);
502510
}
503511

@@ -528,7 +536,9 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
528536

529537
/* integrate the phase and write out if necessary */
530538
if(params->initonly || strlen(outfiles->initfile)){
531-
fprintf(sp1,"Integrating phase\n");
539+
info << pyre::journal::at(__HERE__)
540+
<< "Integrating phase"
541+
<< pyre::journal::endl;
532542
auto unwrappedphase=Array2D<float>(nrow,ncol);
533543
IntegratePhase(wrappedphase,unwrappedphase,flows,nrow,ncol);
534544
if(unwrappedest.size()){
@@ -538,12 +548,16 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
538548

539549
/* return if called in init only; otherwise, free memory and continue */
540550
if(params->initonly){
541-
fprintf(sp1,"Writing output to file %s\n",outfiles->outfile);
551+
info << pyre::journal::at(__HERE__)
552+
<< "Writing output to file " << outfiles->outfile
553+
<< pyre::journal::endl;
542554
WriteOutputFile(mag,unwrappedphase,outfiles->outfile,outfiles,
543555
nrow,ncol);
544556
return(1);
545557
}else{
546-
fprintf(sp2,"Writing initialization to file %s\n",outfiles->initfile);
558+
verbose << pyre::journal::at(__HERE__)
559+
<< "Writing initialization to file " << outfiles->initfile
560+
<< pyre::journal::endl;
547561
WriteOutputFile(mag,unwrappedphase,outfiles->initfile,outfiles,
548562
nrow,ncol);
549563
}
@@ -581,13 +595,20 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
581595

582596
/* main loop: loop over flow increments and sources */
583597
if(!allmasked){
584-
fprintf(sp1,"Running nonlinear network flow optimizer\n");
585-
fprintf(sp1,"Maximum flow on network: %ld\n",mostflow);
586-
fprintf(sp2,"Number of nodes in network: %ld\n",(nrow-1)*(ncol-1)+1);
598+
info << pyre::journal::at(__HERE__)
599+
<< "Running nonlinear network flow optimizer"
600+
<< pyre::journal::endl
601+
<< "Maximum flow on network: " << mostflow
602+
<< pyre::journal::endl;
603+
verbose << pyre::journal::at(__HERE__)
604+
<< "Number of nodes in network: " << ((nrow-1)*(ncol-1)+1)
605+
<< pyre::journal::endl;
587606
while(TRUE){
588607

589-
fprintf(sp1,"Flow increment: %ld (Total improvements: %ld)\n",
590-
nflow,ncycle);
608+
info << pyre::journal::at(__HERE__)
609+
<< "Flow increment: " << nflow
610+
<< " (Total improvements: " << ncycle << ")"
611+
<< pyre::journal::endl;
591612

592613
/* set up the incremental (residual) cost arrays */
593614
SetupIncrFlowCosts(costs,incrcosts,flows,nflow,nrow,narcrow,narcsperrow,
@@ -616,10 +637,14 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
616637

617638
/* show status if verbose */
618639
if(source->row==GROUNDROW){
619-
fprintf(sp3,"Source %ld: (edge ground)\n",isource);
640+
status << pyre::journal::at(__HERE__)
641+
<< "Source " << isource << ": (edge ground)"
642+
<< pyre::journal::endl;
620643
}else{
621-
fprintf(sp3,"Source %ld: row, col = %d, %d\n",
622-
isource,source->row,source->col);
644+
status << pyre::journal::at(__HERE__)
645+
<< "Source " << isource << ": row, col = "
646+
<< source->row << ", " << source->col
647+
<< pyre::journal::endl;
623648
}
624649

625650
/* run the solver, and increment nflowdone if no cycles are found */
@@ -635,9 +660,10 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
635660

636661
/* evaluate and save the total cost (skip if first loop through nflow) */
637662
Array1D<int> dummy;
638-
fprintf(sp2,"Current solution cost: %.16g\n",
639-
(double )EvaluateTotalCost(costs,flows,nrow,ncol,dummy,params,tag));
640-
fflush(NULL);
663+
verbose << pyre::journal::at(__HERE__)
664+
<< "Current solution cost: " << std::fixed << std::setprecision(16)
665+
<< ((double )EvaluateTotalCost(costs,flows,nrow,ncol,dummy,params,tag))
666+
<< pyre::journal::endl;
641667
if(notfirstloop){
642668
oldtotalcost=totalcost;
643669
totalcost=EvaluateTotalCost(costs,flows,nrow,ncol,dummy,params,tag);
@@ -646,7 +672,9 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
646672
}
647673
if(totalcost>oldtotalcost || (n>0 && totalcost==oldtotalcost)){
648674
fflush(NULL);
649-
fprintf(sp1,"Caution: Unexpected increase in total cost\n");
675+
info << pyre::journal::at(__HERE__)
676+
<< "Caution: Unexpected increase in total cost"
677+
<< pyre::journal::endl;
650678
}
651679
if(totalcost > mintotalcost){
652680
nincreasedcostiter++;
@@ -667,8 +695,11 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
667695
mostflow=MaxNonMaskFlow(flows,mag,nrow,ncol);
668696
if(nincreasedcostiter>=mostflow){
669697
fflush(NULL);
670-
fprintf(sp0,"WARNING: Unexpected sustained increase in total cost."
671-
" Breaking loop\n");
698+
auto warnings=pyre::journal::warning_t("isce3.unwrap.snaphu");
699+
warnings << pyre::journal::at(__HERE__)
700+
<< "WARNING: Unexpected sustained increase in total cost."
701+
<< " Breaking loop"
702+
<< pyre::journal::endl;
672703
break;
673704
}
674705

@@ -683,7 +714,9 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
683714
nflow=1;
684715
notfirstloop=TRUE;
685716
}
686-
fprintf(sp2,"Maximum valid flow on network: %ld\n",mostflow);
717+
verbose << pyre::journal::at(__HERE__)
718+
<< "Maximum valid flow on network: " << mostflow
719+
<< pyre::journal::endl;
687720

688721
/* dump flow arrays if necessary */
689722
if(strlen(outfiles->flowfile)){
@@ -715,11 +748,16 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
715748
/* evaluate and display the maximum flow and total cost */
716749
Array1D<int> dummy;
717750
totalcost=EvaluateTotalCost(costs,flows,nrow,ncol,dummy,params,tag);
718-
fprintf(sp1,"Maximum flow on network: %ld\n",mostflow);
719-
fprintf(sp1,"Total solution cost: %.9g\n",(double )totalcost);
751+
info << pyre::journal::at(__HERE__)
752+
<< "Maximum flow on network: " << mostflow
753+
<< pyre::journal::endl << "Total solution cost: "
754+
<< std::fixed << std::setprecision(9) << ((double )totalcost)
755+
<< pyre::journal::endl;
720756

721757
/* integrate the wrapped phase using the solution flow */
722-
fprintf(sp1,"Integrating phase\n");
758+
info << pyre::journal::at(__HERE__)
759+
<< "Integrating phase"
760+
<< pyre::journal::endl;
723761
auto unwrappedphase=Array2D<float>(nrow,ncol);
724762
IntegratePhase(wrappedphase,unwrappedphase,flows,nrow,ncol);
725763

@@ -732,7 +770,9 @@ int UnwrapTile(infileT *infiles, outfileT *outfiles, paramT *params,
732770
FlipPhaseArraySign(unwrappedphase,params,nrow,ncol);
733771

734772
/* write the unwrapped output */
735-
fprintf(sp1,"Writing output to file %s\n",outfiles->outfile);
773+
info << pyre::journal::at(__HERE__)
774+
<< "Writing output to file " << outfiles->outfile
775+
<< pyre::journal::endl;
736776
WriteOutputFile(mag,unwrappedphase,outfiles->outfile,outfiles,
737777
nrow,ncol);
738778

cxx/isce3/unwrap/snaphu/snaphu.h

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <string>
1717

1818
#include <Eigen/Core>
19+
#include <pyre/journal.h>
1920

2021
#include <isce3/except/Error.h>
2122

@@ -99,18 +100,13 @@
99100
#define MINRES SCHAR_MIN
100101
#define PROBCOSTP (-99.999)
101102
#define NULLFILE "/dev/null"
102-
#define DEF_ERRORSTREAM stderr
103-
#define DEF_OUTPUTSTREAM stdout
104-
#define DEF_VERBOSESTREAM NULL
105-
#define DEF_COUNTERSTREAM NULL
106103
#define DEF_INITONLY FALSE
107104
#define DEF_INITMETHOD MSTINIT
108105
#define DEF_UNWRAPPED FALSE
109106
#define DEF_REGROWCONNCOMPS FALSE
110107
#define DEF_EVAL FALSE
111108
#define DEF_WEIGHT 1
112109
#define DEF_COSTMODE TOPO
113-
#define DEF_VERBOSE FALSE
114110
#define DEF_AMPLITUDE TRUE
115111
#define AUTOCALCSTATMAX 0
116112
#define MAXNSHORTCYCLE 8192
@@ -602,7 +598,6 @@ typedef struct paramST{
602598
signed char initmethod=0; /* MST or MCF initialization */
603599
signed char costmode=0; /* statistical cost mode */
604600
signed char dumpall=0; /* dump intermediate files */
605-
signed char verbose=0; /* print verbose output */
606601
signed char amplitude=0; /* intensity data is amplitude, not power */
607602
signed char havemagnitude=0; /* flag: create correlation from other inputs */
608603
signed char flipphasesign=0; /* flag: flip phase and flow array signs */
@@ -998,10 +993,6 @@ int ReadComplexFile(Array2D<float>* mag, Array2D<float>* phase, char *rifile,
998993
int ReadAltSampFile(Array2D<float>* arr1, Array2D<float>* arr2, char *infile,
999994
long linelen, long nlines, tileparamT *tileparams);
1000995
int SetDumpAll(outfileT *outfiles, paramT *params);
1001-
int SetStreamPointers(void);
1002-
int SetVerboseOut(paramT *params);
1003-
int ChildResetStreamPointers(pid_t pid, long tilerow, long tilecol,
1004-
paramT *params);
1005996
int DumpIncrCostFiles(Array2D<incrcostT>& incrcosts, long iincrcostfile,
1006997
long nflow, long nrow, long ncol);
1007998
int MakeTileDir(paramT *params, outfileT *outfiles);
@@ -1096,7 +1087,10 @@ int Write2DArray(Array2D<T>& array, const char *filename,
10961087
}
10971088
if(fclose(fp)){
10981089
fflush(NULL);
1099-
//fprintf(sp0,"WARNING: problem closing file %s (disk full?)\n",realoutfile);
1090+
auto warnings=pyre::journal::warning_t("isce3.unwrap.snaphu");
1091+
warnings << pyre::journal::at(__HERE__)
1092+
<< "WARNING: problem closing file " << realoutfile
1093+
<< " (disk full?)" << pyre::journal::endl;
11001094
}
11011095
return(0);
11021096
}
@@ -1130,7 +1124,10 @@ int Write2DRowColArray(Array2D<T>& array, char *filename, long nrow,
11301124
}
11311125
if(fclose(fp)){
11321126
fflush(NULL);
1133-
//fprintf(sp0,"WARNING: problem closing file %s (disk full?)\n",realoutfile);
1127+
auto warnings=pyre::journal::warning_t("isce3.unwrap.snaphu");
1128+
warnings << pyre::journal::at(__HERE__)
1129+
<< "WARNING: problem closing file " << realoutfile << " (disk full?)"
1130+
<< pyre::journal::endl;
11341131
}
11351132
return(0);
11361133
}
@@ -1329,10 +1326,6 @@ int Read2DRowColFileRows(Array2D<T>* arr, char *filename, long linelen,
13291326
extern char dumpresults_global;
13301327
extern char requestedstop_global;
13311328

1332-
/* ouput stream pointers */
1333-
/* sp0=error messages, sp1=status output, sp2=verbose, sp3=verbose counter */
1334-
extern FILE *sp0, *sp1, *sp2, *sp3;
1335-
13361329
/* node pointer for marking arc not on tree in apex array */
13371330
/* this should be treat as a constant */
13381331
extern nodeT NONTREEARC[1];

0 commit comments

Comments
 (0)