• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

icsm-au / DynAdjust / 13494567994

24 Feb 2025 09:15AM UTC coverage: 81.168% (+2.0%) from 79.161%
13494567994

push

github

web-flow
Merge pull request #234 from icsm-au/1.2.8

Version 1.2.8 (fixes, ehnacements, improved datum management)

6131 of 8137 new or added lines in 90 files covered. (75.35%)

162 existing lines in 33 files now uncovered.

32214 of 39688 relevant lines covered (81.17%)

11775.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.66
/dynadjust/dynadjust/dnasegmentwrapper/dnasegmentwrapper.cpp
1
//============================================================================
2
// Name         : dnasegmentwrapper.cpp
3
// Author       : Roger Fraser
4
// Contributors :
5
// Version      : 1.00
6
// Copyright    : Copyright 2017 Geoscience Australia
7
//
8
//                Licensed under the Apache License, Version 2.0 (the "License");
9
//                you may not use this file except in compliance with the License.
10
//                You may obtain a copy of the License at
11
//               
12
//                http ://www.apache.org/licenses/LICENSE-2.0
13
//               
14
//                Unless required by applicable law or agreed to in writing, software
15
//                distributed under the License is distributed on an "AS IS" BASIS,
16
//                WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
//                See the License for the specific language governing permissions and
18
//                limitations under the License.
19
//
20
// Description  : DynAdjust Network Segmentation Executable
21
//============================================================================
22

23
#include <dynadjust/dnasegmentwrapper/dnasegmentwrapper.hpp>
24

25
using namespace dynadjust;
26

27
bool running;
28
boost::mutex cout_mutex;
29

30
int ParseCommandLineOptions(const int& argc, char* argv[], const boost::program_options::variables_map& vm, project_settings& p)
20✔
31
{
32
        // capture command line arguments
33
        for (int cmd_arg(0); cmd_arg<argc; ++cmd_arg)
150✔
34
        {
35
                 p.s.command_line_arguments += argv[cmd_arg];
130✔
36
                 p.s.command_line_arguments += " ";
130✔
37
        }
38

39
        if (vm.count(PROJECT_FILE))
40✔
40
        {
41
                if (boost::filesystem::exists(p.g.project_file))
4✔
42
                {
43
                        try {
1✔
44
                                CDnaProjectFile projectFile(p.g.project_file, segmentSetting);
1✔
45
                                p = projectFile.GetSettings();
1✔
46
                        }
×
NEW
47
                        catch (const std::runtime_error& e) {
×
NEW
48
                                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
49
                                return EXIT_FAILURE;
×
50
                        }
×
51
                        
52
                        return EXIT_SUCCESS;
1✔
53
                }
54

55
                std::cout << std::endl << "- Error: project file " << p.g.project_file << " does not exist." << std::endl << std::endl;
1✔
56
                return EXIT_FAILURE;
1✔
57
        }
58

59
        if (!vm.count(NETWORK_NAME))
36✔
60
        {
NEW
61
                std::cout << std::endl << "- Nothing to do - no network name specified. " << std::endl << std::endl;  
×
62
                return EXIT_FAILURE;
×
63
        }
64
        
65
        p.g.project_file = formPath<std::string>(p.g.output_folder, p.g.network_name, "dnaproj");
54✔
66

67
        // input files
68
        p.s.asl_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "asl");                // associated stations list
54✔
69
        p.s.aml_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "aml");                // associated measurements list
54✔
70
        p.s.map_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "map");                // station names map
54✔
71
        
72
        if (vm.count(NET_FILE))
36✔
73
                p.s.net_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "net");                // Starting stations file
9✔
74
        
75
        // binary station file location (input)
76
        if (vm.count(BIN_STN_FILE))
36✔
NEW
77
                p.s.bst_file = formPath<std::string>(p.g.input_folder, p.s.bst_file);
×
78
        else
79
                p.s.bst_file = formPath<std::string>(p.g.output_folder, p.g.network_name, "bst");
54✔
80

81
        // binary station file location (input)
82
        if (vm.count(BIN_MSR_FILE))
36✔
NEW
83
                p.s.bms_file = formPath<std::string>(p.g.input_folder, p.s.bms_file);
×
84
        else
85
                p.s.bms_file = formPath<std::string>(p.g.output_folder, p.g.network_name, "bms");
54✔
86

87
        if (!boost::filesystem::exists(p.s.bst_file) || !boost::filesystem::exists(p.s.bms_file))
53✔
88
        {
89
                std::cout << std::endl << "- Nothing to do: ";  
1✔
90
                        
91
                if (p.g.network_name.empty())
1✔
NEW
92
                        std::cout << std::endl << "network name has not been specified specified, and " << std::endl << "               ";  
×
93
                std::cout << p.s.bst_file << " and " << p.s.bms_file << " do not exist." << std::endl << std::endl;  
1✔
94
                return EXIT_FAILURE;
1✔
95
        }
96

97
        // output files
98
        // User supplied segmentation file
99
        if (vm.count(SEG_FILE))
34✔
100
        {
101
                // Does it exist?
102
                if (!boost::filesystem::exists(p.s.seg_file))
2✔
103
                {
104
                        // Look for it in the input folder
NEW
105
                        p.s.seg_file = formPath<std::string>(p.g.input_folder, leafStr<std::string>(p.s.seg_file));
×
106

NEW
107
                        if (!boost::filesystem::exists(p.s.seg_file))
×
108
                        {
NEW
109
                                std::cout << std::endl << "- Error: " <<
×
NEW
110
                                        "Segmentation file " << leafStr<std::string>(p.s.seg_file) << " does not exist." << std::endl << std::endl;  
×
UNCOV
111
                                return EXIT_FAILURE;
×
112
                        }
113
                }
114
        }
115
        else
116
                p.s.seg_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "seg");
48✔
117

118
        // Station appearance file
119
        p.s.sap_file = formPath<std::string>(p.g.input_folder, p.g.network_name, "sap");
51✔
120
        
121
        if (vm.count(TEST_INTEGRITY))
34✔
122
                p.i.test_integrity = 1;
3✔
123

124
        //if (vm.count(SEG_FORCE_CONTIGUOUS))
125
        //        p.s.force_contiguous_blocks = 1;
126

127
        return EXIT_SUCCESS;
128
}
129

130
int main(int argc, char* argv[])
33✔
131
{        
132
        // create banner message
133
        std::string cmd_line_banner;
33✔
134
        fileproc_help_header(&cmd_line_banner);
33✔
135

136
        std::string stnfilename, msrfilename;
33✔
137
        
138
        project_settings p;
33✔
139

140
        boost::program_options::variables_map vm;
33✔
141
        boost::program_options::positional_options_description positional_options;
33✔
142

143
        boost::program_options::options_description standard_options("+ " + std::string(ALL_MODULE_STDOPT), PROGRAM_OPTIONS_LINE_LENGTH);
99✔
144
        boost::program_options::options_description config_options("+ " + std::string(SEGMENT_MODULE_CONFIG), PROGRAM_OPTIONS_LINE_LENGTH);
99✔
145
        boost::program_options::options_description generic_options("+ " + std::string(ALL_MODULE_GENERIC), PROGRAM_OPTIONS_LINE_LENGTH);
99✔
146
        
147
        std::string cmd_line_usage("+ ");
33✔
148
        cmd_line_usage.append(__BINARY_NAME__).append(" usage:  ").append(__BINARY_NAME__).append(" ").append(NETWORK_NAME).append(" [options]");
33✔
149
        boost::program_options::options_description allowable_options(cmd_line_usage, PROGRAM_OPTIONS_LINE_LENGTH);
33✔
150

151
        try {
33✔
152
                // Declare a group of options that will be 
153
                // allowed only on command line                
154
                standard_options.add_options()
33✔
155
                        (PROJECT_FILE_P, boost::program_options::value<std::string>(&p.g.project_file),
33✔
156
                                "Project file name. Full path to project file. If none specified, a new file is created using input-folder and network-name.")
157
                        (NETWORK_NAME_N, boost::program_options::value<std::string>(&p.g.network_name),
33✔
158
                                "Network name. User defined name for all input and output files. Default is \"network#\".")
159
                        (INPUT_FOLDER_I, boost::program_options::value<std::string>(&p.g.input_folder),
33✔
160
                                "Path containing all input files")
161
                        (OUTPUT_FOLDER_O, boost::program_options::value<std::string>(&p.g.output_folder),                // default is ./,
33✔
162
                                "Path for all output files")
163
                        (BIN_STN_FILE, boost::program_options::value<std::string>(&p.s.bst_file),
33✔
164
                                "Binary station file name. Overrides network name.")
165
                        (BIN_MSR_FILE, boost::program_options::value<std::string>(&p.s.bms_file),
33✔
166
                                "Binary measurement file name. Overrides network name.")
167
                        (SEG_FILE, boost::program_options::value<std::string>(&p.s.seg_file),
33✔
168
                                "Segmentation output file name. Overrides network name.")
169
                        ;
170

171
                // Declare a group of options that will be 
172
                // allowed both on command line and in
173
                // config options        
174
                config_options.add_options()
33✔
175
                        (NET_FILE,
33✔
176
                                "Look for a .net file containing stations to be incorporated within the first block.")
177
                        (SEG_STARTING_STN, boost::program_options::value<std::string>(&p.s.seg_starting_stns),
33✔
178
                                "Additional stations to be incorporated within the first block. arg is a comma delimited string \"stn1, stn 2,stn3 , stn 4\".")
179
                        (SEG_MIN_INNER_STNS, boost::program_options::value<UINT32>(&p.s.min_inner_stations),
33✔
180
                                (std::string("Minimum number of inner stations within each block. Default is ")+
99✔
181
                                        StringFromT(p.s.min_inner_stations)+std::string(".")).c_str())
165✔
182
                        (SEG_THRESHOLD_STNS, boost::program_options::value<UINT32>(&p.s.max_total_stations),
33✔
183
                                (std::string("Threshold limit for maximum number of stations per block. Default is ")+
99✔
184
                                        StringFromT(p.s.max_total_stations)+std::string(".")).c_str())
198✔
185
                        (SEG_FORCE_CONTIGUOUS, boost::program_options::value<UINT16>(&p.s.force_contiguous_blocks),
33✔
186
                                (std::string("Treatment of isolated networks:\n")+
132✔
187
                                std::string("  0: Isolated networks as individual blocks ")+
99✔
188
                                (p.s.force_contiguous_blocks==0 ? "(default)\n" : "\n")+
132✔
189
                                std::string("  1: Force production of contiguous blocks ")+
132✔
190
                                (p.s.force_contiguous_blocks==1 ? "(default)" : "")
33✔
191
                                ).c_str())
192
                        (SEG_SEARCH_LEVEL, boost::program_options::value<UINT16>(&p.s.seg_search_level),
33✔
193
                                "Level to which searches should be conducted to find stations with the lowest measurement count. Default is 0.")
194
                        (TEST_INTEGRITY,
33✔
195
                                "Test the integrity of all output files.")
196
                        ;
197

198
                generic_options.add_options()
33✔
199
                        (VERBOSE, boost::program_options::value<UINT16>(&p.g.verbose),
33✔
200
                                std::string("Give detailed information about what ").append(__BINARY_NAME__).append(" is doing.\n  0: No information (default)\n  1: Helpful information\n  2: Extended information\n  3: Debug level information").c_str())
66✔
201
                                (QUIET,
33✔
202
                                        std::string("Suppresses all explanation of what ").append(__BINARY_NAME__).append(" is doing unless an error occurs").c_str())
66✔
203
                                        (VERSION_V, "Display the current program version")
33✔
204
                        (HELP_H, "Show this help message")
33✔
205
                        (HELP_MODULE_H, boost::program_options::value<std::string>(),
33✔
206
                                "Provide help for a specific help category.")
207
                        ;
208

209
                allowable_options.add(standard_options).add(config_options).add(generic_options);
33✔
210

211
                // add "positional options" to handle command line tokens which have no option name
212
                positional_options.add(NETWORK_NAME, -1);
33✔
213
                
214
                boost::program_options::command_line_parser parser(argc, argv);
33✔
215
                store(parser.options(allowable_options).positional(positional_options).run(), vm);
33✔
216
                notify(vm);
27✔
217
        } 
6✔
218
        catch (const std::exception& e) {
6✔
219
                std::cout << "- Error: " << e.what() << std::endl <<
6✔
220
                        cmd_line_banner << allowable_options << std::endl;
6✔
221
                return EXIT_FAILURE;
6✔
222
        }
6✔
223

224
        if (argc < 2)
27✔
225
        {
226
                std::cout << std::endl << "- Nothing to do - no options provided. " << std::endl << std::endl <<
1✔
227
                        cmd_line_banner << allowable_options << std::endl;
1✔
228
                return EXIT_FAILURE;
229
        }
230

231
        if (vm.count(VERSION))
52✔
232
        {
233
                std::cout << cmd_line_banner << std::endl;
1✔
234
                return EXIT_SUCCESS;
235
        }
236

237
        if (vm.count(HELP))
50✔
238
        {
239
                std::cout << cmd_line_banner << allowable_options << std::endl;
1✔
240
                return EXIT_SUCCESS;
241
        }
242

243
        if (vm.count(HELP_MODULE))
48✔
244
        {
245
                std::cout << cmd_line_banner;
4✔
246
                std::string original_text = vm[HELP_MODULE].as<std::string>();
12✔
247
                std::string help_text = str_upper<std::string>(original_text);
4✔
248

249
                if (str_upper<std::string, char>(ALL_MODULE_STDOPT).find(help_text) != std::string::npos) {
12✔
250
                        std::cout << standard_options << std::endl;
1✔
251
                }
252
                else if (str_upper<std::string, char>(SEGMENT_MODULE_CONFIG).find(help_text) != std::string::npos) {
9✔
253
                        std::cout << config_options << std::endl;
1✔
254
                }
255
                else if (str_upper<std::string, char>(ALL_MODULE_GENERIC).find(help_text) != std::string::npos) {
6✔
256
                        std::cout << generic_options << std::endl;
1✔
257
                }
258
                else {
259
                        std::cout << std::endl << "- Error: Help module '" <<
1✔
260
                                original_text << "' is not in the list of options." << std::endl;
4✔
261
                        return EXIT_FAILURE;
262
                }
263

264
                return EXIT_SUCCESS;
3✔
265
        }
8✔
266

267
        bool userSuppliedSegFile(false);
20✔
268
        if (!p.s.seg_file.empty())
20✔
269
                userSuppliedSegFile = true;
1✔
270
        bool userSuppliedBstFile(false);
20✔
271
        if (!p.s.bst_file.empty())
20✔
272
                userSuppliedBstFile = true;
×
273
        bool userSuppliedBmsFile(false);
20✔
274
        if (!p.s.bms_file.empty())
20✔
275
                userSuppliedBmsFile = true;
×
276

277
        if (ParseCommandLineOptions(argc, argv, vm, p) != EXIT_SUCCESS)
20✔
278
                return EXIT_FAILURE;
279

280
        if (vm.count(QUIET))
36✔
281
                p.g.quiet = 1;
×
282
        
283
        if (!p.g.quiet)
18✔
284
        {
285
                std::cout << std::endl << cmd_line_banner;
18✔
286
                
287
                std::cout << "+ Options:" << std::endl; 
18✔
288
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Network name: " <<  p.g.network_name << std::endl;
18✔
289
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Input folder: " << p.g.input_folder << std::endl;
18✔
290
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Output folder: " << p.g.output_folder << std::endl;
18✔
291
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Associated station file: " << p.s.asl_file << std::endl;
18✔
292
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Associated measurement file: " << p.s.aml_file << std::endl;
18✔
293
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Binary station file: " << p.s.bst_file << std::endl;
18✔
294
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Binary measurement file: " << p.s.bms_file << std::endl;
18✔
295
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Segmentation output file: " << p.s.seg_file << std::endl;
18✔
296
                if (!p.s.net_file.empty())
18✔
297
                        std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Block 1 stations file: " << p.s.net_file << std::endl;
3✔
298
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Minimum inner stations: " <<  p.s.min_inner_stations << std::endl;
18✔
299
                std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Block size threshold: " <<  p.s.max_total_stations << std::endl;
18✔
300
                if (!p.s.seg_starting_stns.empty())
18✔
301
                        std::cout << std::setw(PRINT_VAR_PAD) << std::left << "  Additional Block 1 stations: " << p.s.seg_starting_stns << std::endl;
4✔
302
                else if (p.s.net_file.empty())
14✔
303
                        std::cout << "  No initial station specified. The first station will be used." << std::endl;
12✔
304
                
305
                std::cout << std::endl;
18✔
306
        }
307

308
        // Should segment look for a net file?
309
        if (!p.s.net_file.empty())
18✔
310
        {
311
                if (!boost::filesystem::exists(p.s.net_file))
6✔
312
                {
313
                        cout_mutex.lock();
1✔
314
                        std::cout << std::endl <<
1✔
315
                                "- Error: " << p.s.net_file << " does not exist." << std::endl <<
1✔
316
                                "  A file named " << p.g.network_name << ".net must exist in the input folder\n  in order to use this option." << std::endl << std::endl;
1✔
317
                        cout_mutex.unlock();
1✔
318
                        return EXIT_FAILURE;
1✔
319
                }
320
        }
321

322
        dna_segment netSegment;
17✔
323
        boost::posix_time::milliseconds elapsed_time(boost::posix_time::milliseconds(0));
17✔
324
        _SEGMENT_STATUS_ segmentStatus;
17✔
325
        std::string status_msg;
17✔
326

327
        try {
17✔
328
                netSegment.InitialiseSegmentation();
17✔
329
                running = true;
17✔
330

331
                // segment blocks using group thread
332
                boost::thread_group ui_segment_threads;
17✔
333
                if (!p.g.quiet)
17✔
334
                        ui_segment_threads.create_thread(dna_segment_progress_thread(&netSegment, &p));
17✔
335
                ui_segment_threads.create_thread(dna_segment_thread(&netSegment, &p, &segmentStatus, &elapsed_time, &status_msg));
17✔
336
                ui_segment_threads.join_all();
17✔
337
                
338
                switch (netSegment.GetStatus())
17✔
339
                {
340
                case SEGMENT_EXCEPTION_RAISED:
1✔
341
                        running = false;
1✔
342
                        return EXIT_FAILURE;
1✔
343
                default:
16✔
344
                        break;
16✔
345
                }
346

347
                //// print station appearance file
348
                //if (!p.g.quiet)
349
                //        std::cout << "+ Printing station appearance list... ";
350
                //netSegment.WriteStationAppearanceList(p.s.sap_file);
351
                //if (!p.g.quiet)
352
                //        std::cout << "done." << std::endl;
353

354
                if (p.g.verbose > 1 && !p.g.quiet)
16✔
355
                        netSegment.coutSummary(); 
5✔
356

357
                if (segmentStatus != SEGMENT_SUCCESS)
16✔
NEW
358
                        std::cout << status_msg << std::endl;
×
359

360
                if (!p.g.quiet)
16✔
361
                {
362
                        std::cout << "+ Segmentation statistics:" << std::endl;
16✔
363
                        std::cout << std::endl << std::left << "  " <<
16✔
364
                                std::setw(STATION) << "No. blocks" << 
365
                                std::setw(STAT) << "Max size" << 
366
                                std::setw(STAT) << "Min size" << 
367
                                std::setw(STAT) << "Average" <<
368
                                std::setw(STATION) << "Total size" << std::endl;
16✔
369
                        std::cout << "  ";
16✔
370
                        for (UINT32 i(0), j(STATION + STAT*3 + STATION); i<j; ++i)
1,184✔
371
                                std::cout << "-";
1,168✔
372
                        std::cout << std::endl << "  " << std::left <<
16✔
373
                                std::setw(STATION) << netSegment.blockCount() << 
16✔
374
                                std::setw(STAT) << std::setprecision(0) << netSegment.maxBlockSize() << 
16✔
375
                                std::setw(STAT) << std::setprecision(0) << netSegment.minBlockSize() << 
16✔
376
                                std::setw(STAT) << std::setprecision(2) << std::fixed << netSegment.averageblockSize() <<
16✔
377
                                std::setw(STATION) << std::setprecision(0) << netSegment.stationSolutionCount() << std::endl;
16✔
378

379
                        std::cout << std::endl;
16✔
380
                
381
                }
382

383
                if (!p.g.quiet)
16✔
384
                        std::cout << "+ Verifying station connections... ";
16✔
385
                netSegment.VerifyStationConnections();
16✔
386
                if (!p.g.quiet)
16✔
387
                        std::cout << "done." << std::endl;
16✔
388

389
                // print network segmentation block file
390
                if (!p.g.quiet)
16✔
391
                        std::cout << "+ Printing blocks to " << leafStr<std::string>(p.s.seg_file) << "... ";
48✔
392
                netSegment.WriteSegmentedNetwork(p.s.seg_file);
16✔
393
                if (!p.g.quiet)
16✔
394
                        std::cout << "done." << std::endl;
16✔
395

396
                
397
        } 
17✔
398
        catch (const NetSegmentException& e) {
×
NEW
399
                std::cout << std::endl << "- Error: " << e.what() << std::endl;
×
400
                return EXIT_FAILURE;
×
401
        } 
×
NEW
402
        catch (const std::runtime_error& e) {
×
NEW
403
                std::cout << "+ Exception of unknown type: " << e.what();
×
404
                return EXIT_FAILURE;
×
405
        }
×
406

407
        if (!userSuppliedSegFile)
16✔
408
                p.s.seg_file = "";
15✔
409
        if (!userSuppliedBstFile)
16✔
410
                p.s.bst_file = "";
16✔
411
        if (!userSuppliedBmsFile)
16✔
412
                p.s.bms_file = "";
16✔
413

414
        // Look for a project file.  If it exists, open and load it.
415
        // Update the import settings.
416
        // Print the project file. If it doesn't exist, it will be created.
417
        CDnaProjectFile projectFile;
32✔
418
        if (boost::filesystem::exists(p.g.project_file))
32✔
419
                projectFile.LoadProjectFile(p.g.project_file);
16✔
420
        
421
        projectFile.UpdateSettingsSegment(p);
16✔
422
        projectFile.PrintProjectFile();
16✔
423

424
        if (p.g.quiet)
16✔
425
                return EXIT_SUCCESS;
426

427
        std::cout << std::endl << formatedElapsedTime<std::string>(&elapsed_time, "+ Network segmentation took ") << std::endl;
64✔
428
        std::cout << "+ " << p.g.network_name << " is now ready for sequential phased adjustment." << std::endl << std::endl;
16✔
429
        
430
        return EXIT_SUCCESS;
431
}
165✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc