示例#1
0
    bool ConcurrencyConfigurationByProperty::Configure( const ::Configuration *json )
    {
        initConfig( "Extra_Relational_Flag_Type", 
                    m_ExtraRelFlag,
                    json, 
                    MetadataDescriptor::Enum("Extra_Relational_Flag_Type", "TBD", MDD_ENUM_ARGS( ExtraRelationalFlagType ) ) );

        bool ret = true;
        if( m_ExtraRelFlag == ExtraRelationalFlagType::Correlated )
        {
            std::set<std::string> allowable_relationship_types = GetAllowableRelationshipTypes();
            std::vector<std::string> rel_type_strings ;
            initConfigTypeMap( "Correlated_Relationship_Type_Order", &rel_type_strings, "TBD", nullptr, allowable_relationship_types );

            ret = JsonConfigurable::Configure( json );
            if( ret )
            {
                if( rel_type_strings.size() != RelationshipType::COUNT )
                {
                    std::stringstream ss;
                    ss << "Reading '" << m_PropretyValue << ": 'Correlated_Relationship_Type_Order' has " << rel_type_strings.size() << " types and must have " << RelationshipType::COUNT;
                    throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
                }

                for( auto& rel_type_str : rel_type_strings )
                {
                    int rel_type_val = RelationshipType::pairs::lookup_value( rel_type_str.c_str() );

                    // I don't think I need this but just in case.
                    if( rel_type_val == -1 )
                    {
                        std::stringstream ss;
                        ss << "Unknown relationship type = " << rel_type_str;
                        throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
                    }
                    if( std::find( m_RelTypeOrder.begin(), m_RelTypeOrder.end(), RelationshipType::Enum(rel_type_val) ) != m_RelTypeOrder.end() )
                    {
                        std::stringstream ss;
                        ss << "Duplicate(='" << rel_type_str << "') found in 'Correlated_Relationship_Type_Order'.  There must be one and only one of each RelationshipType.";
                        throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
                    }

                    m_RelTypeOrder.push_back( RelationshipType::Enum(rel_type_val) );
                }
            }
        }
        else
        {
            for( int i = 0 ; i < RelationshipType::pairs::count() ; ++i )
            {
                m_RelTypeOrder.push_back( RelationshipType::Enum(RelationshipType::pairs::get_values()[i]) );
            }
        }
        return ret;
    }
示例#2
0
    //
    // NodeSetPolygon class methods
    //
    void
    NodeSetPolygon::parseEmodFormat()
    {
        LOG_INFO("Parsing SHAPE polygon coordinates.\n");

        // take the string points_list
        // parse into lat-long strings
        // separate into individual lat-long coordinates, 
        // allocate polygon point array

        std::string delimiters = " ,";

        // create a vector of strings to hold each successive lat-long coordinate as a string
        vector<string> points_parser;
        std::string points_string = vertices_raw;
        std::string::size_type lastposition = points_string.find_first_not_of(delimiters, 0);
        std::string::size_type position     = points_string.find_first_of(delimiters, lastposition);

        // move through string and extract lat-long coordinates
        while (string::npos != position || string::npos != lastposition)
        {
            points_parser.push_back(points_string.substr(lastposition, position - lastposition));

            lastposition = points_string.find_first_not_of(delimiters, position);

            position = points_string.find_first_of(delimiters, lastposition);
        }

        // allocate memory and update the number of coordinates
        num_points = points_parser.size();
        points_array    = _new_ float[num_points];

        if (num_points % 2 != 0)
        {
            //// ERROR ("Error parsing polygon parameters!\n");
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "Number of polygon parameters is odd." );
        }

        int faultcatcher = 0;

        for (int i = 0; i < num_points; i++)
        {
            std::istringstream temp(points_parser[i]);
            faultcatcher += (temp >> points_array[i]).fail();
        }

        if (faultcatcher)
        {
            // ERROR ("Error parsing polygon parameters!\n");
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "Unspecified problem with polygon parameters." );
        }
        vertices_raw.clear();
    }
示例#3
0
 EventTriggerInternal*  EventTriggerFactory::Add( const std::string& str )
 {
     if( m_MapAll.count( str ) != 0 )
     {
         std::stringstream ss;
         if (std::find(GetBuiltInNames().begin(), GetBuiltInNames().end(), str) != GetBuiltInNames().end())
         {
             ss << "Duplicate event = '" << str << "'. This is a Built-in Event. You do not need to define it. The Built-in events are:" << std::endl;
             for (std::string name : GetBuiltInNames())
             {
                 ss << name << std::endl;
             }
         }
         else
         {
             ss << "Duplicate event = '" << str << "'.  Events names must be unique.";
         }
         throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
     }
     int index = m_VectorAll.size();
     EventTriggerInternal* p_eti = new EventTriggerInternal( str, index );
     m_VectorAll.push_back( p_eti );
     m_MapAll[ str ] = p_eti;
     return p_eti;
 }
    void Action::CheckConfigurationTriggers()
    {
        if( m_EventToBroadcast.empty() || (m_EventToBroadcast == JsonConfigurable::default_string) )
        {
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "You must define Event_To_Broadcast" );
        } 

        switch( m_EventType )
        {
            case EventType::INDIVIDUAL:
            {
                m_TriggerIndividual = EventTriggerFactory::GetInstance()->CreateTrigger( "Event_To_Broadcast", m_EventToBroadcast );
                break;
            }
            case EventType::NODE:
            {
                m_TriggerNode = EventTriggerNodeFactory::GetInstance()->CreateTrigger( "Event_To_Broadcast", m_EventToBroadcast );
                break;
            }
            case EventType::COORDINATOR:
            {
                m_TriggerCoordinator = EventTriggerCoordinatorFactory::GetInstance()->CreateTrigger( "Event_To_Broadcast", m_EventToBroadcast );
                break;
            }
            default:
                throw BadEnumInSwitchStatementException( __FILE__, __LINE__, __FUNCTION__, "Event_Type", m_EventType, EventType::pairs::lookup_key( m_EventType ) );
        }
    }
 void Responder::CheckConfiguration( const Configuration * inputJson )
 {
     if( m_ThresholdType == ThresholdType::PERCENTAGE_EVENTS )
     {
         throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "IncidenceEventCoordinator does not support 'Threshold_Type' == 'PERCENTAGE_EVENTS'" );
     }
 }
 void PairFormationParametersImpl::CheckArraySizes()
 {
     if( joint_probabilities.size() != male_age_bin_count )
     {
         std::stringstream ss ;
         ss << "The " << RelationshipType::pairs::lookup_key( rel_type ) << ":Joint_Probabilities matrix has "
            << joint_probabilities.size() << " rows when it should have one row for each male bin (Number_Age_Bins_Male=" << male_age_bin_count << ")" ;
         throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
     }
     for( int male_bin_index = 0 ; male_bin_index < male_age_bin_count ; male_bin_index++ )
     {
         if( joint_probabilities[ male_bin_index ].size() != female_age_bin_count )
         {
             std::stringstream ss ;
             ss << "The " << RelationshipType::pairs::lookup_key( rel_type ) << ":Joint_Probabilities matrix row " << (male_bin_index+1) << " has "
                << joint_probabilities[ male_bin_index ].size() << " columns when it should have one for each female bin (Number_Age_Bins_Female=" << female_age_bin_count << ")" ;
             throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
         }
     }
 }
    void ActionList::CheckConfiguration()
    {
        if( Size() == 0 )
        {
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "At least one action must be defined for the IncidenceEventCoordinator.");
        }

        // sort into decending order
        std::sort( m_Collection.begin(), m_Collection.end(), GreaterThan );

        // Check if any of the thresholds equal another
        for( int i = 1; i < m_Collection.size(); ++i )
        {
            if( m_Collection[ i - 1 ]->GetThreshold() == m_Collection[ i ]->GetThreshold() )
            {
                std::stringstream ss;
                ss << "More than one action has a Threshold equal to " << m_Collection[ i ]->GetThreshold() << ".  Threshold values must be unique.";
                throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
            }
        }
    }
示例#8
0
    void NodeSTI::SetParameters(NodeDemographicsFactory *demographics_factory, ClimateFactory *climate_factory)
    {
        Node::SetParameters( demographics_factory, climate_factory );

        const std::string SOCIETY_KEY( "Society" );
        if( !demographics.Contains( SOCIETY_KEY ) )
        {
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "Could not find the 'Society' element in the demographics data." );
        }
        std::istringstream iss( demographics[SOCIETY_KEY].ToString() );
        Configuration* p_config = Configuration::Load( iss, "demographics" );
        society->SetParameters( dynamic_cast<IIdGeneratorSTI*>(parent), p_config );
        delete p_config ;
    }
    void CheckForNanOrInf( std::vector<float>& data, const char* source )
    {
        uint32_t index = 0;
        for (float value : data)
        {
            if ( _ISNAN_( value ) )
            {
                // Consider OutOfRangeException( const char * file_name, int line_num, const char* func_name, const char* var_name = nullptr, float value = 0.0f, float value_violated = 0.0f );
                std::ostringstream msg;
                msg << "Found NaN value in " << source << " for current node at offset " << index << '.' << std::endl;
                throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, msg.str().c_str() );
            }

            if ( _ISINF_( value ) )
            {
                // Consider OutOfRangeException( const char * file_name, int line_num, const char* func_name, const char* var_name = nullptr, float value = 0.0f, float value_violated = 0.0f );
                std::ostringstream msg;
                msg << "Found infinite value in " << source << " for current node at offset " << index << '.' << std::endl;
                throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, msg.str().c_str() );
            }

            ++index;
        }
    }
示例#10
0
    void ConcurrencyParameters::Initialize( const std::string& rRelTypeName,
                                            const std::string& rConcurrencyProperty, 
                                            const ::Configuration *json )
    {
        if( rConcurrencyProperty == DEFAULT_PROPERTY )
        {
            ConcurrencyByProperty* p_cbp = new ConcurrencyByProperty( DEFAULT_PROPERTY );
            m_PropertyValueToConcurrencyMap[ DEFAULT_PROPERTY ] = p_cbp;

            initConfigTypeMap( DEFAULT_PROPERTY, p_cbp, "TBD" );
        }
        else
        {
            const IndividualProperty* p_ip = IPFactory::GetInstance()->GetIP( rConcurrencyProperty );

            for( auto kv : p_ip->GetValues<IPKeyValueContainer>()  )
            {
                const std::string& prop_value = kv.GetValueAsString();

                //if( !json->Exist( prop_value ) )
                //{
                //    std::stringstream ss;
                //    ss << "Each type of relationship's Concurrency_Parameters must have all of the Individual Properties defined.  Property Key = " << rConcurrencyProperty;
                //    ss << ", Not Defined Property Value = " << prop_value << " in element = " << rRelTypeName ;
                //    throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
                //}

                ConcurrencyByProperty* p_cbp = new ConcurrencyByProperty( prop_value );
                m_PropertyValueToConcurrencyMap[ prop_value ] = p_cbp;

                initConfigTypeMap( prop_value.c_str(), p_cbp, "TBD" );
            }
        }
        try
        {
            JsonConfigurable::Configure( json );
        }
        catch( DetailedException& re )
        {
            std::stringstream ss ;
            ss << re.GetMsg();
            ss << " Occured while reading the 'Concurrency_Parameters' in '" << rRelTypeName << "' from the demographics.  ";
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
        }
    }
示例#11
0
    bool EventTriggerFactory::Configure( const Configuration* inputJson )
    {
        std::vector<std::string> user_events;
        initConfigTypeMap( "Listed_Events", &user_events, Listed_Events_DESC_TEXT );

        bool ret = JsonConfigurable::Configure( inputJson );

        // ---------------------------------------------------------------------------
        // --- NOTE: we want to execute the following code even if we ar egenerating
        // --- the schema so that we create the internal triggers.
        // ---------------------------------------------------------------------------
        if( ret )
        {
            if (ret && std::find(user_events.begin(), user_events.end(), "") != user_events.end())
            {
                throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "Invalid Event in Listed_Events.  Empty string is an invalid event." );
            }

            // ----------------------------------------------------
            // --- See the top of the file about Built-in triggers
            // ----------------------------------------------------
            release_assert( m_VectorBuiltIn.size() > 0 );
            bool create_built_in = ((m_VectorBuiltIn.size() > 0) && (m_VectorBuiltIn[ 0 ].second->m_pInternal == nullptr));
            if( create_built_in )
            {
                for( auto& entry : m_VectorBuiltIn )
                {
                    entry.second->m_pInternal = Add( entry.first );
                }
            }

            for( auto& ev : user_events )
            {
                CreateUserEventTrigger( ev );
            }
        }

        return ret;
    }
    bool PairFormationParametersImpl::Configure( const Configuration* inputJson )
    {
        initConfig( "Formation_Rate_Type", 
                    formation_rate_type,
                    inputJson, 
                    MetadataDescriptor::Enum("Formation_Rate_Type", "TBD"/*Formation_Rate_Type_DESC_TEXT*/, MDD_ENUM_ARGS( FormationRateType ) ) );

        if( formation_rate_type == FormationRateType::CONSTANT )
        {
            initConfigTypeMap( "Formation_Rate_Constant", &formation_rate_constant, "TBD"/*Formation_Rate_DESC_TEXT*/, 0, 1, 0.001f );
        }
        else if( formation_rate_type == FormationRateType::SIGMOID_VARIABLE_WIDTH_HEIGHT )
        {
            initConfigTypeMap( "Formation_Rate_Sigmoid", &formation_rate_sigmoid, "TBD"/*Formation_Rate_Sigmoid_DESC_TEXT*/ );
        }
        else if( formation_rate_type == FormationRateType::INTERPOLATED_VALUES )
        {
            initConfigComplexType("Formation_Rate_Interpolated_Values", &formation_rate_value_map, "TBD"/*Formation_Rate_Interpolated_Values_DESC_TEXT*/ );
        }
        else
        {
            throw BadEnumInSwitchStatementException( __FILE__, __LINE__, __FUNCTION__, "Formation_Rate_Type", formation_rate_type );
        }

        initConfigTypeMap( "Extra_Relational_Rate_Ratio_Male",   &rate_ratio[Gender::MALE  ], PFA_Extra_Relational_Rate_Ratio_Male_DESC_TEXT,   1.0, FLT_MAX, 1.0f );
        initConfigTypeMap( "Extra_Relational_Rate_Ratio_Female", &rate_ratio[Gender::FEMALE], PFA_Extra_Relational_Rate_Ratio_Female_DESC_TEXT, 1.0, FLT_MAX, 1.0f );

        initConfigTypeMap( "Update_Period",                  &update_period,            "TBD"/*Update_Period_DESC_TEXT*/,         0,    FLT_MAX,    0      );
        initConfigTypeMap( "Number_Age_Bins_Male",           &male_age_bin_count,       Number_Age_Bins_Male_DESC_TEXT,           1,       1000,    1      );
        initConfigTypeMap( "Number_Age_Bins_Female",         &female_age_bin_count,     Number_Age_Bins_Female_DESC_TEXT,         1,       1000,    1      );
        initConfigTypeMap( "Age_of_First_Bin_Edge_Male",     &initial_male_age,         Age_of_First_Bin_Edge_Male_DESC_TEXT,     0,        100,    1      );
        initConfigTypeMap( "Age_of_First_Bin_Edge_Female",   &initial_female_age,       Age_of_First_Bin_Edge_Female_DESC_TEXT,   0,        100,    1      );
        initConfigTypeMap( "Years_Between_Bin_Edges_Male",   &male_age_increment,       Years_Between_Bin_Edges_Male_DESC_TEXT,   0.1f,     100.0f, 1.0f   );
        initConfigTypeMap( "Years_Between_Bin_Edges_Female", &female_age_increment,     Years_Between_Bin_Edges_Female_DESC_TEXT, 0.1f,     100.0f, 1.0f   );
        initConfigTypeMap( "Joint_Probabilities",            &joint_probabilities,      Joint_Probabilities_DESC_TEXT,            0.0,  FLT_MAX,    0.0f   ); 

        bool ret = false;
        bool prev_use_defaults = JsonConfigurable::_useDefaults ;
        bool reset_track_missing = JsonConfigurable::_track_missing;
        JsonConfigurable::_track_missing = false;
        JsonConfigurable::_useDefaults = false ;
        
        try
        {

            ret = JsonConfigurable::Configure( inputJson );

            JsonConfigurable::_useDefaults = prev_use_defaults ;
            JsonConfigurable::_track_missing = reset_track_missing;
        }
        catch( DetailedException& e )
        {
            JsonConfigurable::_useDefaults = prev_use_defaults ;
            JsonConfigurable::_track_missing = reset_track_missing;

            std::stringstream ss ;
            ss << e.GetMsg() << "\n" << "Was reading values for " << RelationshipType::pairs::lookup_key( rel_type ) << "." ;
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
        }
        catch( json::Exception& e )
        {
            JsonConfigurable::_useDefaults = prev_use_defaults ;
            JsonConfigurable::_track_missing = reset_track_missing;

            std::stringstream ss ;
            ss << e.what() << "\n" << "Was reading values for " << RelationshipType::pairs::lookup_key( rel_type ) << "." ;
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
        }

        if( ret )
        {
            CheckArraySizes();

            InitializeAgeBins( Gender::MALE,   male_age_bin_count,   initial_male_age,   male_age_increment   );
            InitializeAgeBins( Gender::FEMALE, female_age_bin_count, initial_female_age, female_age_increment );

            InitializeMarginalValues();
            InitializeCumulativeProbabilities();
        }
        return ret ;
    }
示例#13
0
    void ConcurrencyConfiguration::Initialize( const ::Configuration *json )
    {
        initConfigTypeMap( "Probability_Person_Is_Behavioral_Super_Spreader", &m_ProbSuperSpreader, Probability_Person_Is_Behavioral_Super_Spreader_DESC_TEXT, 0.0, 1.0f, 0.001f );
        initConfigTypeMap( "Individual_Property_Name", &m_PropertyKey, "TBD", DEFAULT_PROPERTY );
        try
        {
            JsonConfigurable::Configure( json );
        }
        catch( DetailedException& re )
        {
            std::stringstream ss ;
            ss << re.GetMsg();
            ss << " Occured while reading 'Concurrency_Configuration' from the demographics.  ";
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
        }

        if( m_PropertyKey.empty() )
        {
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "'Individual_Property_Name' cannot be empty string." );
        }
        else if( m_PropertyKey == DEFAULT_PROPERTY )
        {
            ConcurrencyConfigurationByProperty* p_ccbp = new ConcurrencyConfigurationByProperty( DEFAULT_PROPERTY );
            m_PropertyValueToConfig[ DEFAULT_PROPERTY ] = p_ccbp;
            initConfigTypeMap( DEFAULT_PROPERTY, p_ccbp, "TBD" );
        }
        else
        {
            std::set<std::string> keys = IPFactory::GetInstance()->GetKeysAsStringSet();
            if( keys.count( m_PropertyKey ) == 0 )
            {
                std::stringstream ss;
                ss << "'Individual_Property_Name' (='" << m_PropertyKey << "') in 'Concurrency_Configuration' in the demograhics is not a defined Individual Property.\n";
                ss << "Valid Individual Properties are: ";
                if( keys.size() == 0 )
                {
                    ss << "(No properties are defined.)";
                }
                else
                {
                    for( auto& k : keys )
                    {
                        ss << "'" << k << "' ";
                    }
                }
                throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
            }

            const IndividualProperty* p_ip = IPFactory::GetInstance()->GetIP( m_PropertyKey );
            for( auto kv : p_ip->GetValues<IPKeyValueContainer>() )
            {
                const std::string& prop_value = kv.GetValueAsString();

                ConcurrencyConfigurationByProperty* p_ccbp = new ConcurrencyConfigurationByProperty( prop_value );
                m_PropertyValueToConfig[ prop_value ] = p_ccbp ;

                initConfigTypeMap( prop_value.c_str(), p_ccbp, "TBD" );
            }
        }
        try
        {
            JsonConfigurable::Configure( json );
        }
        catch( DetailedException& re )
        {
            std::stringstream ss ;
            ss << re.GetMsg();
            ss << " Occured while reading 'Concurrency_Configuration' from the demographics.  ";
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, ss.str().c_str() );
        }
    }
示例#14
0
    bool
    NodeLevelHealthTriggeredIV::Configure(
        const Configuration * inputJson
    )
    {
        JsonConfigurable::_useDefaults = InterventionFactory::useDefaults;

        if( JsonConfigurable::_dryrun || inputJson->Exist( "Actual_NodeIntervention_Config" ) )
        {
            initConfigComplexType( "Actual_NodeIntervention_Config", &actual_node_intervention_config, BT_Actual_NodeIntervention_Config_DESC_TEXT );
        }
        if( JsonConfigurable::_dryrun || inputJson->Exist( "Actual_IndividualIntervention_Config" ) )
        {
            initConfigComplexType( "Actual_IndividualIntervention_Config", &actual_individual_intervention_config, BT_Actual_IndividualIntervention_Config_DESC_TEXT );
        }
        if( !JsonConfigurable::_dryrun && 
            ( ( inputJson->Exist( "Actual_IndividualIntervention_Config" ) &&  inputJson->Exist( "Actual_NodeIntervention_Config" )) || 
              (!inputJson->Exist( "Actual_IndividualIntervention_Config" ) && !inputJson->Exist( "Actual_NodeIntervention_Config" )) ) )
        {
            throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "You must specify either 'Actual_IndividualIntervention_Config' or 'Actual_NodeIntervention_Config' (but do not specify both)." );
        }

        initConfigTypeMap( "Distribute_On_Return_Home", &distribute_on_return_home, Distribute_On_Return_Home_DESC_TEXT, false );

        initConfigTypeMap("Duration", &max_duration, BT_Duration_DESC_TEXT, -1.0f, FLT_MAX, -1.0f ); // -1 is a convention for indefinite duration

        initConfigTypeMap( "Blackout_Period", &blackout_period, Blackout_Period_DESC_TEXT, 0.0f, FLT_MAX, 0.0f );
        initConfigTypeMap( "Blackout_Event_Trigger", &blackout_event_trigger, Blackout_Event_Trigger_DESC_TEXT );
        initConfigTypeMap( "Blackout_On_First_Occurrence", &blackout_on_first_occurrence, Blackout_On_First_Occurrence_DESC_TEXT, false );

        initConfigComplexType( "Node_Property_Restrictions", &node_property_restrictions, NLHTIV_Node_Property_Restriction_DESC_TEXT );

        demographic_restrictions.ConfigureRestrictions( this, inputJson );

        // --------------------------------------------------------------------------------------------------------------------
        // --- Phase 0 - Pre V2.0 - Trigger_Condition was an enum and users had to have all indivual events in the enum list.
        // --- Phase 1 -     V2.0 - Trigger_Condition was an enum but TriggerString and TriggerList were added to allow the 
        // ---                      user to use new User Defined events (i.e. strings).
        // --- Phase 2 - 11/12/15 - Trigger_Condition is now a string and so users don't need to use Trigger_Condition_String
        // ---                      in order to use the User Defined events.  However, we are leaving support here for 
        // ---                      Trigger_Condition_String for backward compatibility (and I'm lazy).
        // --- Phase 3 - 11/9/16    Consolidate so that the user only defines Trigger_Condition_List
        // --------------------------------------------------------------------------------------------------------------------
        JsonConfigurable::_useDefaults = InterventionFactory::useDefaults; // Why???
        initConfigTypeMap( "Trigger_Condition_List", &m_trigger_conditions, NLHTI_Trigger_Condition_List_DESC_TEXT );

        bool retValue = BaseNodeIntervention::Configure( inputJson );

        //this section copied from standardevent coordinator
        if( retValue && !JsonConfigurable::_dryrun )
        {
            demographic_restrictions.CheckConfiguration();
            if( inputJson->Exist( "Actual_IndividualIntervention_Config" ) )
            {
                InterventionValidator::ValidateIntervention( actual_individual_intervention_config._json, inputJson->GetDataLocation() );
                using_individual_config = true;
            }
            else if( inputJson->Exist( "Actual_NodeIntervention_Config" ) )
            {
                InterventionValidator::ValidateIntervention( actual_node_intervention_config._json, inputJson->GetDataLocation() );
                using_individual_config = false;
            }

            event_occured_list.resize( EventTriggerFactory::GetInstance()->GetNumEventTriggers() );

            bool blackout_configured = (inputJson->Exist("Blackout_Event_Trigger")) || (inputJson->Exist("Blackout_Period")) || (inputJson->Exist("Blackout_On_First_Occurrence"));
            bool blackout_all_configured = (inputJson->Exist("Blackout_Event_Trigger")) && (inputJson->Exist("Blackout_Period")) && (inputJson->Exist("Blackout_On_First_Occurrence"));
            if (blackout_configured && !blackout_all_configured)
            {
                std::vector<string> blackout_missing_str;
                if( !inputJson->Exist("Blackout_Event_Trigger") )       blackout_missing_str.push_back("Blackout_Event_Trigger");
                if( !inputJson->Exist("Blackout_Period") )              blackout_missing_str.push_back("Blackout_Period");
                if( !inputJson->Exist("Blackout_On_First_Occurrence") ) blackout_missing_str.push_back("Blackout_On_First_Occurrence");

                throw MissingParameterFromConfigurationException(__FILE__, __LINE__, __FUNCTION__, inputJson->GetDataLocation().c_str(), blackout_missing_str, " All three Blackout parameters must be configured.");
            }

            if( distribute_on_return_home )
            {
                if( (std::find( m_trigger_conditions.begin(), m_trigger_conditions.end(), EventTrigger::Emigrating ) != m_trigger_conditions.end()) ||
                    (std::find( m_trigger_conditions.begin(), m_trigger_conditions.end(), EventTrigger::Immigrating ) != m_trigger_conditions.end()) )
                {
                    throw InvalidInputDataException( __FILE__, __LINE__, __FUNCTION__, "When using Distribute_On_Return_Home, you cannot also use Emigrating or Immigrating." );
                }
                m_trigger_conditions.push_back( EventTrigger::Emigrating );
                m_trigger_conditions.push_back( EventTrigger::Immigrating );
            }
        }
        JsonConfigurable::_useDefaults = false;
        return retValue;    
    }