From a04ed5637faec76a8e155fdf0efc78bed41c692f Mon Sep 17 00:00:00 2001 From: Patrick Thomas <pthomas@caltech.edu> Date: Wed, 17 May 2023 14:53:55 -0700 Subject: [PATCH 1/4] Turned the message structure into a class. Changes to make the printing of messages to the terminal and to the gui use the same variable. Changes to some formatting due to rerunning clang-format. --- src/dtt/filterwiz/FilterFile.cc | 644 +++++++++++++++------------ src/dtt/filterwiz/FilterMessage.cc | 101 +++-- src/dtt/filterwiz/FilterMessage.hh | 36 +- src/dtt/filterwiz/FilterModule.cc | 128 +++--- src/dtt/filterwiz/TLGFilterWizard.cc | 2 +- 5 files changed, 513 insertions(+), 398 deletions(-) diff --git a/src/dtt/filterwiz/FilterFile.cc b/src/dtt/filterwiz/FilterFile.cc index 2fda2f91..7878ff59 100644 --- a/src/dtt/filterwiz/FilterFile.cc +++ b/src/dtt/filterwiz/FilterFile.cc @@ -505,13 +505,14 @@ namespace filterwiz const char* modulename = ( *mod ).getName( ); const char* sectionname = ( *mod )[ i ].getName( ); - cerr << "Error updating module " << modulename - << ", section " << sectionname << endl; - file_message_vec.push_back( - create_message( ERROR, - "Error updating module %s, section %s", - modulename, - sectionname ) ); + message_t msg( + ERROR, + format( "Error updating module %s, section %s", + modulename, + sectionname ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return false; } } @@ -526,9 +527,10 @@ namespace filterwiz // Note that the file name is the full path of the file. if ( !filename ) { - cerr << "Illegal file name" << endl; - file_message_vec.push_back( - create_message( ERROR, "Illegal file name" ) ); + message_t msg( ERROR, format( "Illegal file name" ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return false; } string oldfilename = fFilename; @@ -537,9 +539,11 @@ namespace filterwiz gdsbase::mmap mfile( filename, std::ios_base::in ); if ( !mfile ) { - cerr << "Unable to open file " << filename << endl; - file_message_vec.push_back( - create_message( ERROR, "Unable to open file %s", filename ) ); + message_t msg( ERROR, + format( "Unable to open file %s", filename ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + fFilename = oldfilename; return false; } @@ -550,12 +554,13 @@ namespace filterwiz if ( stat( fFilename.c_str( ), &fStat ) ) { // An error occurred getting stat. - cerr << "stat error, " << strerror( errno ) << endl; - file_message_vec.push_back( - create_message( ERROR, - "stat error for file %s, %s", - filename, - strerror( errno ) ) ); + + message_t msg( ERROR, + format( "stat error for file %s, %s", + filename, + strerror( errno ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } bool succ = read( (const char*)mfile.get( ), mfile.size( ), false ) == @@ -609,9 +614,11 @@ namespace filterwiz ( strncmp( beg, kMagic, strlen( kMagic ) ) != 0 ) ) { clear( ); - cerr << "Not an online filter file" << endl; - file_message_vec.push_back( - create_message( ERROR, "Not an online filter file" ) ); + + message_t msg( ERROR, format( "Not an online filter file" ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return 0; } // first look for filter module names. Scan the entire file for lines @@ -640,12 +647,12 @@ namespace filterwiz } else { - cerr << linenum << ": " - << "Illegal file module name " << *i << endl; - file_message_vec.push_back( - create_message( ERROR, - "Illegal file module name %s", - i->c_str( ) ) ); + message_t msg( linenum, + ERROR, + format( "Illegal file module name %s", + i->c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } } @@ -700,13 +707,13 @@ namespace filterwiz { const char* temp = string( p, linelen ).c_str( ); - cerr << linenum << ": " - << "Illegal sampling rate specification:" << endl - << " " << temp << endl; - file_message_vec.push_back( create_message( + message_t msg( + linenum, ERROR, - "Illegal sampling rate specification: %s", - temp ) ); + format( "Illegal sampling rate specification: %s", + temp ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } } @@ -751,26 +758,25 @@ namespace filterwiz } else { - cerr << linenum << ": " - << "Sampling rate for unknown filter module " - << tok[ 0 ] << endl; - file_message_vec.push_back( create_message( - ERROR, - "Sampling rate for unknown filter module %s", - tok[ 0 ].c_str( ) ) ); + message_t msg( linenum, + ERROR, + format( "Sampling rate for unknown " + "filter module %s", + tok[ 0 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } else { const char* temp = string( p, linelen ).c_str( ); - - cerr << linenum << ": " - << "Illegal sampling rate specification:" << endl - << " " << temp << endl; - file_message_vec.push_back( create_message( + message_t msg( + linenum, ERROR, - "Illegal sampling rate specification: %s", - temp ) ); + format( "Illegal sampling rate specification: %s", + temp ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } } @@ -799,13 +805,13 @@ namespace filterwiz if ( ( tok.size( ) > 0 ) && ismodname( tok[ 0 ].c_str( ) ) && !find( tok[ 0 ].c_str( ) ) ) { - cout << linenum << ": " - << "Warning: Filter module " << tok[ 0 ] << " added." - << endl; - file_message_vec.push_back( - create_message( WARNING, - "Filter module %s added", - tok[ 0 ].c_str( ) ) ); + message_t msg( linenum, + WARNING, + format( "Filter module %s added.", + tok[ 0 ].c_str( ) ) ); + cout << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + // Create a new module with the file's sample rate and add // it to the file's module list. add( tok[ 0 ].c_str( ), getFSample( ) ); @@ -818,10 +824,12 @@ namespace filterwiz if ( fModules.empty( ) ) { clear( ); - cerr << linenum << ": " - << "No filter module specification" << endl; - file_message_vec.push_back( - create_message( ERROR, "No filter module specification" ) ); + + message_t msg( + linenum, ERROR, format( "No filter module specification" ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return 0; } @@ -833,14 +841,16 @@ namespace filterwiz if ( i->getFSample( ) <= 1E-10 ) { i->defaultFSample( ); - cout << linenum << ": " - << "Error: Setting sampling rate of " << i->getName( ) - << " to be " << i->getFSample( ) << endl; - file_message_vec.push_back( create_message( + + message_t msg( + linenum, ERROR, - "No sample rate specified. Setting rate of %s to be %f", - i->getName( ), - i->getFSample( ) ) ); + format( + "No sample rate specified. Setting rate of %s to be %f", + i->getName( ), + i->getFSample( ) ) ); + cout << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } @@ -895,42 +905,52 @@ namespace filterwiz !isnum( tok[ 8 ] ) || !isnum( tok[ 9 ] ) || !isnum( tok[ 10 ] ) || !isnum( tok[ 11 ] ) ) { - cerr << linenum << ": " - << "Illegal filter section:" << endl - << " " << string( p, linelen ) << endl; - file_message_vec.push_back( - create_message( ERROR, - "Illegal filter section: '%s' [0]=%d", - string( p, linelen ).c_str( ), - *p ) ); + + message_t msg( linenum, + ERROR, + format( "Illegal filter section: '%s' [0]=%d", + string( p, linelen ).c_str( ), + *p ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } FilterModule* mod = find( tok[ 0 ].c_str( ) ); if ( !mod ) { - cerr << linenum << ": " - << "Unknown filter module " << tok[ 0 ] << endl; - file_message_vec.push_back( create_message( - ERROR, "Unknown filter module %s", tok[ 0 ].c_str( ) ) ); + message_t msg( + linenum, + ERROR, + format( "Unknown filter module %s", tok[ 0 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } int index = atoi( tok[ 1 ].c_str( ) ); if ( ( index < 0 ) || ( index >= kMaxFilterSections ) ) { - cerr << linenum << ": " - << "Illegal section number " << tok[ 1 ] << endl; - file_message_vec.push_back( create_message( - ERROR, "Illegal section number %s", tok[ 1 ].c_str( ) ) ); + message_t msg( + linenum, + ERROR, + format( "Illegal section number %s", tok[ 1 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } input_switching inpsw = ( input_switching )( atoi( tok[ 2 ].c_str( ) ) / 10 ); if ( ( inpsw != kAlwaysOn ) && ( inpsw != kZeroHistory ) ) { - cerr << linenum << ": " - << "Illegal input switch " << tok[ 2 ] << endl; - file_message_vec.push_back( create_message( - ERROR, "Illegal input switch %s", tok[ 2 ].c_str( ) ) ); + message_t msg( + linenum, + ERROR, + format( "Illegal input switch %s", tok[ 2 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } output_switching outsw = @@ -938,10 +958,14 @@ namespace filterwiz if ( ( outsw != kImmediately ) && ( outsw != kRamp ) && ( outsw != kInputCrossing ) && ( outsw != kZeroCrossing ) ) { - cerr << linenum << ": " - << "Illegal output switch " << tok[ 2 ] << endl; - file_message_vec.push_back( create_message( - ERROR, "Illegal output switch %s", tok[ 2 ].c_str( ) ) ); + + message_t msg( + linenum, + ERROR, + format( "Illegal output switch %s", tok[ 2 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } int sosnum = atoi( tok[ 3 ].c_str( ) ); @@ -956,10 +980,13 @@ namespace filterwiz } if ( ( sosnum < 1 ) || ( sosnum > kMaxFilterSOS ) ) { - cerr << linenum << ": " - << "Illegal SOS number " << tok[ 3 ] << endl; - file_message_vec.push_back( create_message( - ERROR, "Illegal SOS number %s", tok[ 3 ].c_str( ) ) ); + message_t msg( + linenum, + ERROR, + format( "Illegal SOS number %s", tok[ 3 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } double ramp = 0; @@ -973,18 +1000,17 @@ namespace filterwiz ramp = atof( tok[ 4 ].c_str( ) ) / mod->getFSample( ); if ( ramp <= 0 ) { - cerr << linenum << ": " - << "Illegal ramp time " << tok[ 4 ] << endl; - file_message_vec.push_back( create_message( - ERROR, - "Module %s section %d, Illegal ramp time %s", - tok[ 0 ].c_str( ), - index, - tok[ 4 ].c_str( ) ) ); - file_message_vec.push_back( - create_message( ERROR, - " Setting output switch to " - "Immediate, ramp time to 0!" ) ); + message_t msg( linenum, + ERROR, + format( "Module %s section %d, Illegal ramp " + "time %s. Setting output switch to " + "Immediate, ramp time to 0!", + tok[ 0 ].c_str( ), + index, + tok[ 4 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + // Try to fix the filter by changing the output switch and // ramp time. outsw = kImmediately; @@ -997,30 +1023,31 @@ namespace filterwiz timeout = atof( tok[ 5 ].c_str( ) ) / mod->getFSample( ); if ( tolerance < 0 ) { - cerr << linenum << ": " - << "Illegal switch tolerance " << tok[ 4 ] << endl; - file_message_vec.push_back( create_message( + message_t msg( + linenum, ERROR, - "Module %s section %d, Illegal switch tolerance %s", - tok[ 0 ].c_str( ), - index, - tok[ 4 ].c_str( ) ) ); - file_message_vec.push_back( create_message( - ERROR, " Setting switch tolerance to 0!" ) ); + format( "Module %s section %d, Illegal switch " + "tolerance %s. Setting switch tolerance to 0!", + tok[ 0 ].c_str( ), + index, + tok[ 4 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + tolerance = 0.0; } if ( timeout < 0 ) { - cerr << linenum << ": " - << "Illegal timeout " << tok[ 5 ] << endl; - file_message_vec.push_back( create_message( - ERROR, - "Module %s section %d, Illegal timeout %s", - tok[ 0 ].c_str( ), - index, - tok[ 5 ].c_str( ) ) ); - file_message_vec.push_back( - create_message( ERROR, " Setting timeout to 0!" ) ); + message_t msg( linenum, + ERROR, + format( "Module %s section %d, Illegal " + "timeout %s. Setting timeout to 0!", + tok[ 0 ].c_str( ), + index, + tok[ 5 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + timeout = 0.0; } break; @@ -1044,23 +1071,25 @@ namespace filterwiz p = nextline( p, end, linelen ); if ( p >= end ) { - cerr << linenum << ": " - << "Not enough lines in file" << endl; - file_message_vec.push_back( - create_message( ERROR, "Not enough lines in file" ) ); + message_t msg( + linenum, ERROR, format( "Not enough lines in file" ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + break; } tokens( p, linelen, tok, true ); } if ( ( sosnum > 0 ) && ( (int)tok.size( ) != 8 + 4 * sosnum ) ) { - cerr << linenum << ": " - << "Not enough second order sections for " << tok[ 0 ] - << endl; - file_message_vec.push_back( - create_message( ERROR, - "Not enough second order sections for %s", - tok[ 0 ].c_str( ) ) ); + message_t msg( + linenum, + ERROR, + format( "Not enough second order sections for %s", + tok[ 0 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } bool ok = true; @@ -1071,13 +1100,14 @@ namespace filterwiz } if ( !ok ) { - cerr << linenum << ": " - << "Filter coefficients for " << tok[ 0 ] - << " are not all numbers" << endl; - file_message_vec.push_back( create_message( + message_t msg( + linenum, ERROR, - "Filter coefficients for %s are not all numbers", - tok[ 0 ].c_str( ) ) ); + format( "Filter coefficients for %s are not all numbers", + tok[ 0 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } // Finally we have a valid filter section! @@ -1222,35 +1252,33 @@ namespace filterwiz } else if ( !mod ) { - cerr << linenum << ": " - << "Design for unknown filter module " << tok[ 0 ] - << endl; - file_message_vec.push_back( create_message( + message_t msg( + linenum, ERROR, - "Design for unknown filter module %s", - tok[ 0 ].c_str( ) ) ); + format( "Design for unknown filter module %s", + tok[ 0 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } else { - cerr << linenum << ": " - << "Illegal section number " << tok[ 0 ] << "/" - << tok[ 1 ] << endl; - file_message_vec.push_back( - create_message( ERROR, - "Illegal section number %s/%s", - tok[ 0 ].c_str( ), - tok[ 1 ].c_str( ) ) ); + message_t msg( linenum, + ERROR, + format( "Illegal section number %s/%s", + tok[ 0 ].c_str( ), + tok[ 1 ].c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } else { - cerr << linenum << ": " - << "Illegal design specification:" << endl - << " " << string( p, linelen ) << endl; - file_message_vec.push_back( - create_message( ERROR, - "Illegal design specification: %s", - string( p, linelen ).c_str( ) ) ); + message_t msg( linenum, + ERROR, + format( "Illegal design specification: %s", + string( p, linelen ).c_str( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); } } } @@ -1321,9 +1349,12 @@ namespace filterwiz { if ( errmsg ) sprintf( errmsg, "Unable to open file %s", filename ); - cerr << "Unable to open file " << filename << endl; - file_message_vec.push_back( - create_message( ERROR, "Unable to open file %s", filename ) ); + + message_t msg( ERROR, + format( "Unable to open file %s", filename ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return false; } int size = 0; @@ -1340,12 +1371,14 @@ namespace filterwiz if ( errmsg ) strcpy( errmsg, "Memory exhausted attempting to write file" ); - cerr << "Memory exhausted attempting to write file" << filename - << endl; - file_message_vec.push_back( create_message( + + message_t msg( ERROR, - "Memory exhausted attempting to write file %s", - filename ) ); + format( "Memory exhausted attempting to write file %s", + filename ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + return ( false ); } // Assuming we got the memory we requested, attempt to fill the @@ -1544,16 +1577,19 @@ namespace filterwiz if ( !sect.designEmpty( ) ) { //--- iirorder suppresses zeroes at fNy ... we don't want - //this int order = iirorder (sect.filter().get()); + // this int order = iirorder (sect.filter().get()); int order = iirsoscount( sect.filter( ).get( ) ); if ( order < 0 ) { - cerr << "Not an IIR filter" << endl; - file_message_vec.push_back( create_message( + message_t msg( ERROR, - "Module %s, section %s - Not an IIR filter.", - mod->getName( ), - sect.getName( ) ) ); + format( + "Module %s, section %s - Not an IIR filter.", + mod->getName( ), + sect.getName( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + continue; } //--- Reserve space for zeroes. @@ -1567,14 +1603,16 @@ namespace filterwiz if ( !iir2z( sect.filter( ).get( ), nba, coeff, "o" ) ) { - cerr << "Unable to obtain online filter coefficients" - << endl; - file_message_vec.push_back( - create_message( ERROR, - "Module %s, section %s - Unable to " - "obtain online filter coefficients", - mod->getName( ), - sect.getName( ) ) ); + + message_t msg( + ERROR, + format( "Module %s, section %s - Unable to " + "obtain online filter coefficients", + mod->getName( ), + sect.getName( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + delete[] coeff; continue; } @@ -1600,14 +1638,16 @@ namespace filterwiz ( sosnum < 1 ) ) || ( sosnum > kMaxFilterSOS ) ) { - cerr << "Invalid number of SOSs " << sosnum << endl; - file_message_vec.push_back( - create_message( ERROR, - "Module %s, section %s - Invalid " - "number of SOS (%d)", - mod->getName( ), - sect.getName( ), - sosnum ) ); + message_t msg( + ERROR, + format( "Module %s, section %s - Invalid " + "number of SOS (%d)", + mod->getName( ), + sect.getName( ), + sosnum ) ); + cerr << msg.get_fmt_str( ) << endl; + file_message_vec.push_back( msg ); + delete[] coeff; continue; // Don't write the filter section. } @@ -1713,23 +1753,26 @@ namespace filterwiz if ( coeffs[ 0 ] != 0 || coeffs[ 1 ] != 0 || coeffs[ 2 ] != 0 || coeffs[ 3 ] != 0 ) { - file_message_vec.push_back( create_message( - WARNING, - "SOS was corrected to 'empty' in filter %d module %s", - section, - mod.getName( ) ) ); + message_t msg( WARNING, + format( "SOS was corrected to 'empty' in " + "filter %d module %s", + section, + mod.getName( ) ) ); + file_message_vec.push_back( msg ); } return false; } if ( sos_list.size( ) > 1 ) { - file_message_vec.push_back( - create_message( WARNING, - "2 SOSs were produced from one " - "input when correcting filter %d module %s", - section, - mod.getName( ) ) ); + message_t msg( + WARNING, + format( "2 SOSs were produced from one " + "input when correcting filter %d module %s", + section, + mod.getName( ) ) ); + file_message_vec.push_back( msg ); + poles_ok = false; } @@ -1740,18 +1783,20 @@ namespace filterwiz coeffs[ 3 ] != corrected_sos.B2( ) ) { poles_ok = false; - file_message_vec.push_back( create_message( + message_t msg( WARNING, - "filter %d module %s had at least one pole with\n" - " a low frequency. Poles with frequency less than " - "10^(-6)\n" - " as fraction of sample frequency will suffer from low " - "precision.\n" - "%s", - section, - mod.getName( ), - correct_on_load ? " The pole(s) were corrected.\n" - : "" ) ); + format( "filter %d module %s had at least one pole with\n" + " a low frequency. Poles with frequency less than " + "10^(-6)\n" + " as fraction of sample frequency will suffer " + "from low " + "precision.\n" + "%s", + section, + mod.getName( ), + correct_on_load ? " The pole(s) were corrected.\n" + : "" ) ); + file_message_vec.push_back( msg ); // don't actually write out the "corrected" values. // We are just going to produce warnings. coeffs[0] = @@ -1764,12 +1809,13 @@ namespace filterwiz catch ( const std::exception& e ) { std::exception_ptr p = std::current_exception( ); - file_message_vec.push_back( - create_message( ERROR, - "error in SOS in filter %d of mod %s: %s", - section, - mod.getName( ), - e.what( ) ) ); + + message_t msg( ERROR, + format( "error in SOS in filter %d of mod %s: %s", + section, + mod.getName( ), + e.what( ) ) ); + file_message_vec.push_back( msg ); poles_ok = false; } @@ -2005,27 +2051,37 @@ namespace filterwiz // # ETMX_R0_S_ACT 8 notch(1,10,30) 12 3.0 0.0 notch_1 // // Note the following: + module_name must be listed in the MODULES section - // at the head of the filter file. If it doesn't exist, the filter + // at the head of the filter file. If it doesn't exist, + // the filter // definition is ignored. // + section_number is in the range 0-9 // + design_string must be a valid string containing no - //spaces. + // spaces. // + switching is a two digit integer consisting of // (input switching + output switching), where input - //switching is one of: 10 - Input is always applied to filter 20 - Input - //switch will switch with output switch output switching is one of: 1 - - //Immediate - switch off as soon as commanded 2 - Ramp - ramp over time - //specified in ramp_time 3 - Input crossing - output will switch when the - //filter input and output are within a given value of each other + // switching is one of: 10 - + // Input is always applied to filter 20 - Input switch will switch with + // output switch output + // switching is one of: 1 - Immediate - switch off + // as soon as commanded 2 - Ramp - ramp over time + // specified in ramp_time 3 - Input crossing - output + // will switch when the + // filter input and output are within a given + // value of each other // (value is in ramp_time field) // 4 - Zero crossing - output switch when input crosses - //zero. - // + ramp_time can be a time (which is multiplied by sampling rate - //to obtain ramp cycles) or a floating point value for input crossing + // zero. + // + ramp_time can be a time (which is multiplied by + // sampling rate + // to obtain ramp cycles) or a floating point value + // for input crossing // + timeout_time - time in seconds. If the output switching - //isn't met in this time, the output will switch anyway. - // + section_name - Filter section name used in EPICS displays - //of the standard filter module. No whitespace allowed. + // isn't met in this time, the output will switch + // anyway. + // + section_name - Filter section name used in EPICS + // displays + // of the standard filter module. No whitespace + // allowed. // // These functions are part of the FilterFile class because the merge needs // to be done on a filter file that's already been read. Return 0 if @@ -2106,11 +2162,10 @@ namespace filterwiz // The first token has to be a "#" if ( !ishash( tok[ 0 ] ) ) { - merge_message_vec.push_back( - create_message( ERROR, - linenum, - "Line %d: Must start with '#'", - linenumber ) ); + message_t msg( + linenumber, ERROR, format( "Must start with '#'" ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } @@ -2119,23 +2174,23 @@ namespace filterwiz if ( !ismodname( tok[ 1 ] ) || !( module = find( tok[ 1 ].c_str( ) ) ) ) { - merge_message_vec.push_back( create_message( - ERROR, - linenum, - "Line %d: Invalid module name %s or module not found", - linenumber, - tok[ 1 ].c_str( ) ) ); + message_t msg( linenumber, + ERROR, + format( "Invalid module name %s or " + "module not found", + tok[ 1 ].c_str( ) ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } // The third token needs to be a section number, range 0-9 if ( !isintnum( tok[ 2 ] ) ) { - merge_message_vec.push_back( - create_message( ERROR, - linenum, - "Line %d: Invalid section number", - linenumber ) ); + message_t msg( + linenumber, ERROR, format( "Invalid section number" ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } else @@ -2143,12 +2198,12 @@ namespace filterwiz section_number = atoi( tok[ 2 ].c_str( ) ); if ( section_number < 0 || section_number > 9 ) { - merge_message_vec.push_back( create_message( - ERROR, - linenum, - "Line %d: Invalid section number %d", - linenumber, - section_number ) ); + message_t msg( linenumber, + ERROR, + format( "Invalid section number %d", + section_number ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } } @@ -2156,11 +2211,11 @@ namespace filterwiz // Fifth token is a switching parameter. Needs to be an int. if ( !isintnum( tok[ 4 ] ) ) { - merge_message_vec.push_back( - create_message( ERROR, - linenum, - "Line %d: Invalid switching parameter", - linenumber ) ); + message_t msg( linenumber, + ERROR, + format( "Invalid switching parameter" ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } else @@ -2169,12 +2224,13 @@ namespace filterwiz ( input_switching )( atoi( tok[ 4 ].c_str( ) ) / 10 ); if ( ( inpsw != kAlwaysOn ) && ( inpsw != kZeroHistory ) ) { - merge_message_vec.push_back( - create_message( ERROR, - linenum, - "Line %d: Invalid input switch %d", - linenumber, - atoi( tok[ 4 ].c_str( ) ) / 10 ) ); + message_t msg( + linenumber, + ERROR, + format( "Invalid input switch %d", + atoi( tok[ 4 ].c_str( ) ) / 10 ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } outsw = @@ -2183,12 +2239,14 @@ namespace filterwiz ( outsw != kInputCrossing ) && ( outsw != kZeroCrossing ) ) { - merge_message_vec.push_back( - create_message( ERROR, - linenum, - "Line %d: Invalid output switch %d", - linenumber, - atoi( tok[ 4 ].c_str( ) ) % 10 ) ); + + message_t msg( + linenumber, + ERROR, + format( "Invalid output switch %d", + atoi( tok[ 4 ].c_str( ) ) % 10 ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } } @@ -2213,11 +2271,11 @@ namespace filterwiz timeout_time = 0.0; if ( ramp_time <= 0 ) { - merge_message_vec.push_back( create_message( - ERROR, - linenum, - "Line %d: Ramp time must be greater than 0.", - linenumber ) ); + message_t msg( linenumber, + ERROR, + format( "Ramp time must be " + "greater than 0." ) ); + merge_message_vec.push_back( msg ); invalid = 1; } break; @@ -2230,20 +2288,22 @@ namespace filterwiz timeout_time = atof( tok[ 6 ].c_str( ) ); if ( tolerance < 0 ) { - merge_message_vec.push_back( create_message( - ERROR, - linenum, - "Line %d: Tolerance must be greater than 0.", - linenumber ) ); + message_t msg( linenumber, + ERROR, + format( "Tolerance must be " + "greater than 0." ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } if ( timeout_time < 0 ) { - merge_message_vec.push_back( create_message( + message_t msg( + linenumber, ERROR, - linenum, - "Line %d: Timeout must be greater than 0.", - linenumber ) ); + format( "Timeout must be greater than 0." ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } break; @@ -2271,11 +2331,13 @@ namespace filterwiz if ( !( section->update( ) ) ) { - merge_message_vec.push_back( create_message( + message_t msg( ERROR, - linenum, - "Creation of filter failed from design = %s\n", - section->getDesign( ) ) ); + format( + "Creation of filter failed from design = %s\n", + section->getDesign( ) ) ); + merge_message_vec.push_back( msg ); + invalid = 1; } else diff --git a/src/dtt/filterwiz/FilterMessage.cc b/src/dtt/filterwiz/FilterMessage.cc index 3e9427e3..5daaa002 100644 --- a/src/dtt/filterwiz/FilterMessage.cc +++ b/src/dtt/filterwiz/FilterMessage.cc @@ -1,9 +1,25 @@ -#include "FilterMessage.hh" #include <cstdarg> #include <algorithm> #include <iostream> #include <functional> +#include "FilterMessage.hh" + +std::string +format( const char* format, ... ) +{ + char buffer[ 1024 ]; + va_list argp; + + // Textbook case of handling variable arguments being passed to another + // function that takes variable arguments. + va_start( argp, format ); + vsnprintf( buffer, sizeof( buffer ), format, argp ); + va_end( argp ); + + return std::string( buffer ); +} + std::string message_level_to_string( message_level_t level ) { @@ -18,49 +34,47 @@ message_level_to_string( message_level_t level ) } } -message_t -create_message( message_level_t level, const char* msg, ... ) +message_t::message_t( message_level_t level, std::string text ) { - char mbuf[ 1024 ]; - char msgbuf[ 1024 ]; - va_list argp; - - // Textbook case of handling variable arguments being passed to another - // function that takes variable arguments. - va_start( argp, msg ); - vsprintf( msgbuf, msg, argp ); - va_end( argp ); + this->has_line_number = false; - message_t message; - message.level = level; - message.text = message_level_to_string( level ) + std::string( ": " ) + - std::string( msgbuf ); - - return message; + this->level = level; + this->text = text; } -message_t -create_message( message_level_t level, int line_num, const char* msg, ... ) +message_t::message_t( int line_number, message_level_t level, std::string text ) { - char mbuf[ 1024 ]; - char msgbuf[ 1024 ]; - va_list argp; + this->has_line_number = true; + this->line_number = line_number; - // Textbook case of handling variable arguments being passed to another - // function that takes variable arguments. - va_start( argp, msg ); - vsnprintf( msgbuf, sizeof( msgbuf ), msg, argp ); - va_end( argp ); + this->level = level; + this->text = text; +} - // Create a string from the msgbuf to add to the message vector - snprintf( mbuf, sizeof( mbuf ), "line %d: %s", line_num, msgbuf ); +std::string +message_t::get_fmt_str( ) const +{ + char fmt_str[ 1024 ]; - message_t message; - message.level = level; - message.text = message_level_to_string( level ) + std::string( ": " ) + - std::string( mbuf ); + if ( this->has_line_number ) + { + snprintf( fmt_str, + sizeof( fmt_str ), + "%i: %s: %s", + this->line_number, + message_level_to_string( this->level ).c_str( ), + this->text.c_str( ) ); + } + else + { + snprintf( fmt_str, + sizeof( fmt_str ), + "%s: %s", + message_level_to_string( this->level ).c_str( ), + this->text.c_str( ) ); + } - return message; + return std::string( fmt_str ); } std::vector< message_t > @@ -68,17 +82,22 @@ message_vec_filter_level( std::vector< message_t > message_vec, message_level_t level ) { std::vector< message_t > filtered_message_vec; - std::copy_if( message_vec.begin( ), - message_vec.end( ), - std::back_inserter( filtered_message_vec ), - [ level ]( message_t m ) { return m.level == level; } ); + + std::copy_if( + message_vec.begin( ), + message_vec.end( ), + std::back_inserter( filtered_message_vec ), + [ level ]( message_t m ) { return m.get_level( ) == level; } ); + return filtered_message_vec; } void print_message_vec( std::vector< message_t > message_vec ) { - auto print = []( const message_t& m ) { std::cout << m.text << std::endl; }; + auto print = []( const message_t& m ) { + std::cout << m.get_fmt_str( ) << std::endl; + }; std::for_each( message_vec.cbegin( ), message_vec.cend( ), print ); } @@ -91,7 +110,7 @@ message_vec_to_string_vec( std::vector< message_t > message_vec ) std::transform( message_vec.begin( ), message_vec.end( ), std::back_inserter( string_vec ), - std::mem_fn( &message_t::text ) ); + std::mem_fn( &message_t::get_fmt_str ) ); return string_vec; } diff --git a/src/dtt/filterwiz/FilterMessage.hh b/src/dtt/filterwiz/FilterMessage.hh index 521d83f4..225922c8 100644 --- a/src/dtt/filterwiz/FilterMessage.hh +++ b/src/dtt/filterwiz/FilterMessage.hh @@ -4,24 +4,44 @@ #include <string> #include <vector> +std::string format( const char*, ... ); + enum message_level_t { WARNING, ERROR }; -struct message_t +std::string message_level_to_string( ); + +class message_t { - message_level_t level; - std::string text; -}; +public: + message_t( message_level_t, std::string ); + + message_t( int, message_level_t, std::string ); -std::string message_level_to_string( message_level_t level ); + message_level_t + get_level( ) + { + return this->level; + } -message_t create_message( message_level_t level, const char* msg, ... ); + std::string + get_text( ) + { + return this->text; + } -message_t -create_message( message_level_t level, int line_num, const char* msg, ... ); + std::string get_fmt_str( ) const; + +private: + message_level_t level; + std::string text; + + bool has_line_number; + int line_number; +}; std::vector< message_t > message_vec_filter_level( std::vector< message_t > message_vec, diff --git a/src/dtt/filterwiz/FilterModule.cc b/src/dtt/filterwiz/FilterModule.cc index d851ef81..a77779f9 100644 --- a/src/dtt/filterwiz/FilterModule.cc +++ b/src/dtt/filterwiz/FilterModule.cc @@ -175,12 +175,14 @@ namespace filterwiz << fSect[ i ].getName( ) << ", creating one: " << s << endl; - message_vec->push_back( create_message( + message_t msg( WARNING, - "Module %s section %d: Missing design string, " - "a new string will be generated.", - getName( ), - i ) ); + format( "Module %s section %d: Missing design string, " + "a new string will be generated.", + getName( ), + i ) ); + cerr << msg.get_fmt_str( ) << endl; + message_vec->push_back( msg ); fSect[ i ].setDesign( s ); } @@ -199,13 +201,14 @@ namespace filterwiz { ok = false; - message_vec->push_back( create_message( + message_t msg( ERROR, - "Filter module %s section %d: Failed to create " - "filter from design string %s", - getName( ), - i, - fSect[ i ].getDesign( ) ) ); + format( "Filter module %s section %d: Failed to create " + "filter from design string %s", + getName( ), + i, + fSect[ i ].getDesign( ) ) ); + message_vec->push_back( msg ); } } // get filter from coefficients @@ -232,16 +235,18 @@ namespace filterwiz { if ( zero[ k ].Real( ) > 0 ) { - message_t message = create_message( - WARNING, - "Module %s section %d has a zero in the " - "right half s-plane\n" - "at (%f, %f) rad/s.\n", - getName( ), - i, - zero[ k ].Real( ), - zero[ k ].Imag( ) ); - message_vec->push_back( message ); + message_t msg = + message_t( WARNING, + format( "Module %s section %d " + "has a zero in the " + "right half s-plane\n" + "at (%f, %f) rad/s.\n", + getName( ), + i, + zero[ k ].Real( ), + zero[ k ].Imag( ) ) ); + cerr << msg.get_fmt_str( ) << endl; + message_vec->push_back( msg ); } } delete[] zero; @@ -251,13 +256,14 @@ namespace filterwiz { ok = false; - message_vec->push_back( create_message( + message_t msg( ERROR, - "Filter module %s section %d: Failed to create " - "filter from coefficients.", - getName( ), - i ) ); - + format( + "Filter module %s section %d: Failed to create " + "filter from coefficients.", + getName( ), + i ) ); + message_vec->push_back( msg ); break; } } @@ -272,21 +278,23 @@ namespace filterwiz { if ( noDesign ) { - message_vec->push_back( create_message( - WARNING, - "Module %s section %d: Missing design string, a " - "new string will be generated.", - getName( ), - i ) ); + message_t msg( WARNING, + format( "Module %s section %d: Missing " + "design string, a " + "new string will be generated.", + getName( ), + i ) ); + message_vec->push_back( msg ); } else { - message_vec->push_back( - create_message( ERROR, - "Module %s section %d: Mismatch " - "between design and coefficients.", - getName( ), - i ) ); + message_t msg( + ERROR, + format( "Module %s section %d: Mismatch " + "between design and coefficients.", + getName( ), + i ) ); + message_vec->push_back( msg ); } } } @@ -323,14 +331,18 @@ namespace filterwiz // Should also issue a warning! fSect[ j ].setDesign( "" ); fSect[ j ].filter( ).reset( ); - message_vec->push_back( create_message( + + message_t msg( WARNING, - "Module %s section %d: Could not create an " - "design string that produces the filter " - "exactly.\n" - " Design string is left blank\n", - getName( ), - i ) ); + format( "Module %s section %d: Could not " + "create an " + "design string that produces the " + "filter " + "exactly.\n" + " Design string is left blank\n", + getName( ), + i ) ); + message_vec->push_back( msg ); } } } @@ -376,12 +388,13 @@ namespace filterwiz << fSect[ i ].getName( ) << ", creating one: " << s << endl; - message_vec->push_back( create_message( + message_t msg( WARNING, - "Module %s section %d: Missing design string, " - "a new string will be generated.", - getName( ), - i ) ); + format( "Module %s section %d: Missing design string, " + "a new string will be generated.", + getName( ), + i ) ); + message_vec->push_back( msg ); fSect[ i ].setDesign( s ); } @@ -399,13 +412,14 @@ namespace filterwiz catch ( ... ) { ok = false; - message_vec->push_back( create_message( + message_t msg( ERROR, - "Filter module %s section %d: Failed to create " - "filter from design string %s", - getName( ), - i, - fSect[ i ].getDesign( ) ) ); + format( "Filter module %s section %d: Failed to create " + "filter from design string %s", + getName( ), + i, + fSect[ i ].getDesign( ) ) ); + message_vec->push_back( msg ); } } diff --git a/src/dtt/filterwiz/TLGFilterWizard.cc b/src/dtt/filterwiz/TLGFilterWizard.cc index 6255fa52..614cc537 100644 --- a/src/dtt/filterwiz/TLGFilterWizard.cc +++ b/src/dtt/filterwiz/TLGFilterWizard.cc @@ -4186,7 +4186,7 @@ namespace filterwiz } //-------------------------------- The button layout was set here, - //but.. delete fButtonLayout; fButtonLayout = + // but.. delete fButtonLayout; fButtonLayout = // new TGLayoutHints (kLHintsExpandX | kLHintsTop, 15, 15, 10, 6); return num + nstd; } -- GitLab From 1829820dfd4122fd895477b88c46227e8ce6c3fb Mon Sep 17 00:00:00 2001 From: Patrick Thomas <pthomas@caltech.edu> Date: Wed, 17 May 2023 16:44:43 -0700 Subject: [PATCH 2/4] Fixes to the Python bindings and tests to match the changes in the error handling data structure. --- src/python/foton/filterfile_pybind.cc | 4 +-- src/python/foton/foton_unit_test.py | 48 +++++++++++++-------------- src/python/foton/pyfilterfile_test.py | 20 +++++------ 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/python/foton/filterfile_pybind.cc b/src/python/foton/filterfile_pybind.cc index 1fb32eb3..482c4853 100644 --- a/src/python/foton/filterfile_pybind.cc +++ b/src/python/foton/filterfile_pybind.cc @@ -24,8 +24,8 @@ PYBIND11_MODULE(pyfilterfile, m) { .export_values(); py::class_<message_t>(m, "FilterMessage") - .def_readwrite("level", &message_t::level) - .def_readwrite("text", &message_t::text); + .def("get_level", &message_t::get_level) + .def("get_fmt_str", &message_t::get_fmt_str); py::class_<FilterFile>(m, "FilterFile") diff --git a/src/python/foton/foton_unit_test.py b/src/python/foton/foton_unit_test.py index 0b6500a8..0f61f694 100644 --- a/src/python/foton/foton_unit_test.py +++ b/src/python/foton/foton_unit_test.py @@ -183,10 +183,10 @@ class TestFotonMethods(unittest.TestCase): self.file.correct_on_load = True self.file.write_file(tmpfile) - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"warnings={warnings}") print(f"errors={errors}") self.assertNotEqual(len(warnings), 0) @@ -203,13 +203,13 @@ class TestFotonMethods(unittest.TestCase): design = f'butter("LowPass",4,{f:g})' fd = foton.FilterDesign(design, self.section.rate) self.module[4].set_filterdesign(fd) - print(f"starting messages={[m.text for m in self.file.ff.getFileMessages()]}") + print(f"starting messages={[m.get_fmt_str() for m in self.file.ff.getFileMessages()]}") butter_txt = self.file.ff.write_string() - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"warnings={warnings}") print(f"errors={errors}") self.assertTrue(warnings) @@ -219,10 +219,10 @@ class TestFotonMethods(unittest.TestCase): print(f"correct_on_load={ff.ff.correct_on_load}") ff.ff.read_string(butter_txt) - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, ff.ff.getFileMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, ff.ff.getFileMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, ff.ff.getFileMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, ff.ff.getFileMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"read warnings={warnings}") print(f"read errors={errors}") self.assertTrue(warnings) @@ -234,7 +234,7 @@ class TestFotonMethods(unittest.TestCase): butter_txt2 = ff.ff.write_string() ff2 = foton.FilterFile() ff2.ff.read_string(butter_txt2) - errors = [m.text for m in ff2.ff.getFileMessages() if m.level == filterfile.message_level_t.ERROR] + errors = [m.get_fmt_str() for m in ff2.ff.getFileMessages() if m.get_level() == filterfile.message_level_t.ERROR] print(f"read2 errors = {errors}") self.assertEqual(len(errors), 0) @@ -255,13 +255,13 @@ class TestFotonMethods(unittest.TestCase): design = f'butter("LowPass",4,{f:g})' fd = foton.FilterDesign(design, self.section.rate) self.module[4].set_filterdesign(fd) - print(f"starting messages={[m.text for m in self.file.ff.getFileMessages()]}") + print(f"starting messages={[m.get_fmt_str() for m in self.file.ff.getFileMessages()]}") butter_txt = self.file.ff.write_string() - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, self.file.ff.getFileMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, self.file.ff.getFileMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"warnings c={warnings}") print(f"errors c={errors}") self.assertTrue(warnings) @@ -272,10 +272,10 @@ class TestFotonMethods(unittest.TestCase): print(f"correct_on_load c={ff.ff.correct_on_load}") ff.ff.read_string(butter_txt) - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, ff.ff.getFileMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, ff.ff.getFileMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, ff.ff.getFileMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, ff.ff.getFileMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"read warnings c={warnings}") print(f"read errors c={errors}") self.assertTrue(warnings) @@ -288,7 +288,7 @@ class TestFotonMethods(unittest.TestCase): ff2 = foton.FilterFile() ff2.ff.correct_on_load = True ff2.ff.read_string(butter_txt2) - errors = [m.text for m in ff2.ff.getFileMessages() if m.level == filterfile.message_level_t.ERROR] + errors = [m.get_fmt_str() for m in ff2.ff.getFileMessages() if m.get_level() == filterfile.message_level_t.ERROR] print(f"read2 errors c= {errors}") self.assertEqual(len(errors), 0) diff --git a/src/python/foton/pyfilterfile_test.py b/src/python/foton/pyfilterfile_test.py index 07ddfa62..5c4f2ea2 100644 --- a/src/python/foton/pyfilterfile_test.py +++ b/src/python/foton/pyfilterfile_test.py @@ -174,10 +174,10 @@ class FilterFileTest(unittest.TestCase): ret_code = self.ff.merge(self.fname) self.assertEqual(ret_code, -1) - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, self.ff.getMergeMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, self.ff.getMergeMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, self.ff.getMergeMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, self.ff.getMergeMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"merge warnings={warnings}") print(f"merge errors={errors}") self.assertFalse(warnings) @@ -186,10 +186,10 @@ class FilterFileTest(unittest.TestCase): def test_errors(self): self.ff.read_file(self.fname) - warnings = list(filter(lambda m: m.level == filterfile.message_level_t.WARNING, self.ff.getMergeMessages())) - warnings = list(map(lambda m: m.text, warnings)) - errors = list(filter(lambda m: m.level == filterfile.message_level_t.ERROR, self.ff.getMergeMessages())) - errors = list(map(lambda m: m.text, errors)) + warnings = list(filter(lambda m: m.get_level() == filterfile.message_level_t.WARNING, self.ff.getMergeMessages())) + warnings = list(map(lambda m: m.get_fmt_str(), warnings)) + errors = list(filter(lambda m: m.get_level() == filterfile.message_level_t.ERROR, self.ff.getMergeMessages())) + errors = list(map(lambda m: m.get_fmt_str(), errors)) print(f"merge warnings={warnings}") print(f"merge errors={errors}") self.assertFalse(warnings) @@ -220,7 +220,7 @@ class FilterFileTest(unittest.TestCase): ff2.correct_on_load = True ff2.read_string(ff_text2) - errors = [m.text for m in ff2.getFileMessages() if m.level == filterfile.message_level_t.ERROR] + errors = [m.get_fmt_str() for m in ff2.getFileMessages() if m.get_level() == filterfile.message_level_t.ERROR] print(f"col errors={errors}") self.assertEqual(len(errors), 1) @@ -229,7 +229,7 @@ class FilterFileTest(unittest.TestCase): ff3.correct_on_load = False ff3.read_string(ff_text2) - errors = [m.text for m in ff3.getFileMessages() if m.level == filterfile.message_level_t.ERROR] + errors = [m.get_fmt_str() for m in ff3.getFileMessages() if m.get_level() == filterfile.message_level_t.ERROR] print(f"col errors={errors}") self.assertEqual(len(errors), 0) -- GitLab From b313ed15b72109e39a920f8f8f91b40745168d4e Mon Sep 17 00:00:00 2001 From: Patrick Thomas <pthomas@caltech.edu> Date: Thu, 18 May 2023 13:04:01 -0700 Subject: [PATCH 3/4] Added more detail to the notifications about deleting filter modules upon saving. --- src/dtt/filterwiz/FilterFile.cc | 8 +++++++- src/dtt/filterwiz/FilterMessage.cc | 2 +- src/dtt/filterwiz/TLGFilterWizard.cc | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/dtt/filterwiz/FilterFile.cc b/src/dtt/filterwiz/FilterFile.cc index 7878ff59..da7e3a64 100644 --- a/src/dtt/filterwiz/FilterFile.cc +++ b/src/dtt/filterwiz/FilterFile.cc @@ -922,7 +922,13 @@ namespace filterwiz message_t msg( linenum, ERROR, - format( "Unknown filter module %s", tok[ 0 ].c_str( ) ) ); + format( + "%s could not be found in the # MODULES header.\nIt " + "was likely removed by the RCG. Its design is not " + "being loaded.\nIf this file is saved then no " + "information on it (including its design\nand " + "coefficients) will be present in the saved file.\n", + tok[ 0 ].c_str( ) ) ); cerr << msg.get_fmt_str( ) << endl; file_message_vec.push_back( msg ); diff --git a/src/dtt/filterwiz/FilterMessage.cc b/src/dtt/filterwiz/FilterMessage.cc index 5daaa002..5e4418b8 100644 --- a/src/dtt/filterwiz/FilterMessage.cc +++ b/src/dtt/filterwiz/FilterMessage.cc @@ -60,7 +60,7 @@ message_t::get_fmt_str( ) const { snprintf( fmt_str, sizeof( fmt_str ), - "%i: %s: %s", + "Line %i: %s: %s", this->line_number, message_level_to_string( this->level ).c_str( ), this->text.c_str( ) ); diff --git a/src/dtt/filterwiz/TLGFilterWizard.cc b/src/dtt/filterwiz/TLGFilterWizard.cc index 614cc537..5f39ffba 100644 --- a/src/dtt/filterwiz/TLGFilterWizard.cc +++ b/src/dtt/filterwiz/TLGFilterWizard.cc @@ -1842,12 +1842,22 @@ namespace filterwiz // delete filters. if ( !fFilterFile.emptyFileMessages( ) ) { + std::string msg = + std::string( + "There were issues encountered when this file was " + "loaded.\nThese issues may include one or more filter " + "modules not listed in the # MODULES header.\nAny filter " + "modules not listed in the # MODULES header\nmay be " + "completely removed in the saved file.\n This includes " + "their design and coefficients.\nPlease check the list of " + "issues encountered loading the file for this case before " + "proceeding.\n" ) + + std::string( "\nProceed and save anyway?" ); Int_t ret; new TGMsgBox( gClient->GetRoot( ), fParent, "Warning", - "There were errors reading the file!\n*** SAVING MAY " - "DELETE FILTERS! ***\nContinue?", + msg.c_str( ), kMBIconExclamation, kMBYes | kMBNo | kMBCancel, &ret ); -- GitLab From 64a2f4b69fd4412d1065d5c646b5d7ccbee6e9aa Mon Sep 17 00:00:00 2001 From: Patrick Thomas <pthomas@caltech.edu> Date: Thu, 18 May 2023 16:30:21 -0700 Subject: [PATCH 4/4] Fixed some poorly formatted comments. --- src/dtt/filterwiz/FilterFile.cc | 60 +++++++++++++++------------------ 1 file changed, 27 insertions(+), 33 deletions(-) diff --git a/src/dtt/filterwiz/FilterFile.cc b/src/dtt/filterwiz/FilterFile.cc index da7e3a64..9177f0eb 100644 --- a/src/dtt/filterwiz/FilterFile.cc +++ b/src/dtt/filterwiz/FilterFile.cc @@ -28,7 +28,7 @@ namespace filterwiz ////////////////////////////////////////////////////////////////////////// // // - // Parsing utilities // + // Parsing utilities // // // ////////////////////////////////////////////////////////////////////////// typedef vector< string > tokenlist; @@ -327,7 +327,7 @@ namespace filterwiz ////////////////////////////////////////////////////////////////////////// // // - // FilterFile // + // FilterFile // // // ////////////////////////////////////////////////////////////////////////// // A FilterFile has a couple of protected members, fFilename which is a @@ -2057,37 +2057,31 @@ namespace filterwiz // # ETMX_R0_S_ACT 8 notch(1,10,30) 12 3.0 0.0 notch_1 // // Note the following: + module_name must be listed in the MODULES section - // at the head of the filter file. If it doesn't exist, - // the filter - // definition is ignored. - // + section_number is in the range 0-9 - // + design_string must be a valid string containing no - // spaces. - // + switching is a two digit integer consisting of - // (input switching + output switching), where input - // switching is one of: 10 - - // Input is always applied to filter 20 - Input switch will switch with - // output switch output - // switching is one of: 1 - Immediate - switch off - // as soon as commanded 2 - Ramp - ramp over time - // specified in ramp_time 3 - Input crossing - output - // will switch when the - // filter input and output are within a given - // value of each other - // (value is in ramp_time field) - // 4 - Zero crossing - output switch when input crosses - // zero. - // + ramp_time can be a time (which is multiplied by - // sampling rate - // to obtain ramp cycles) or a floating point value - // for input crossing - // + timeout_time - time in seconds. If the output switching - // isn't met in this time, the output will switch - // anyway. - // + section_name - Filter section name used in EPICS - // displays - // of the standard filter module. No whitespace - // allowed. + // at the head of the filter file. If it doesn't exist, + // the filter definition is ignored. + // + section_number is in the range 0-9 + // + design_string must be a valid string containing no spaces. + // + switching is a two digit integer consisting of + // (input switching + output switching), + // where input switching is one of: + // 10 - Input is always applied to filter + // 20 - Input switch will switch with output + // + // switch output switching is one of: + // 1 - Immediate - switch off as soon as commanded + // 2 - Ramp - ramp over time specified in ramp_time + // 3 - Input crossing - output will switch when the + // filter input and output are within a given + // value of each other (value is in ramp_time field) + // 4 - Zero crossing - output switch when input crosses zero. + // + ramp_time can be a time (which is multiplied by sampling rate + // to obtain ramp cycles) or a floating point value + // for input crossing + // + timeout_time - time in seconds. If the output switching + // isn't met in this time, the output will switch anyway. + // + section_name - Filter section name used in EPICS + // displays of the standard filter module. No whitespace + // allowed. // // These functions are part of the FilterFile class because the merge needs // to be done on a filter file that's already been read. Return 0 if -- GitLab