Build Your Own Reference Model#
ACCERT now accept user-defined model with user defined code of account structure.
Build your own account table#
Create a raw_account.csv file, that table should includes with the following columns: ind, code_of_account, account_description, total_cost, level, supaccount, alg_name, fun_unit, variables.
ind: [REQUIRED] Unique identifier for each account
code_of_account: [REQUIRED] Code of account
account_description: [Optional] Description of the account
total_cost: [REQUIRED] Total cost of the account unit in dollars
level: [REQUIRED] Level of the account
supaccount: [REQUIRED] Superior account
alg_name: [Optional] Algorithm name to calculate the cost of the account
fun_unit: [Optional] Algorithm function output unit
variables:[Optional] Variables used in the algorithm
ind |
code_of_account |
account_description |
total_cost |
level |
supaccount |
alg_name |
fun_unit |
variables |
|---|---|---|---|---|---|---|---|---|
1 |
2 |
User defined direct cost |
1000000000 |
0 |
||||
2 |
21 |
User defined total cost 21 |
700000000 |
1 |
2 |
|||
3 |
211 |
User defined total cost 211 |
100000000 |
2 |
21 |
ud211 |
million |
v1, v2, v3 |
4 |
212 |
User defined total cost 212 |
200000000 |
2 |
21 |
ud212 |
dollar |
v5, v8, v7 |
5 |
213 |
User defined total cost 213 |
400000000 |
2 |
21 |
|||
7 |
2131 |
User defined total cost 2131 |
150000000 |
3 |
213 |
ud2131 |
million |
v3, v2, v5 |
8 |
2132 |
User defined total cost 27 |
250000000 |
3 |
213 |
ud2132 |
million |
v8, v4, v6 |
9 |
22 |
example account without algorithm |
300000000 |
2 |
22 |
Make sure that all the hierarchy accounts can be connected from the top level to the bottom level. And for each account, the supaccount should be the code_of_account of its parent account. If any algorithm is applied to the account, the alg_name should be specified. The fun_unit is the unit of the algorithm function. The variables are the variables that are used in the algorithm. Total cost is the in the unit of dollar.
Run the following command to generate the user-defined account table.
python ACCERT/src/scripts/gen_user_defined.py
The script will generate a user_defined_account.csv file in the same directory, and also generate a raw_variable_automated_generated.csv file. The user_defined_account.csv file will be used in the next step to generate the user-defined algorithm table. The raw_variable_automated_generated.csv file will be filled in by the user to provide the values of the variables used in the algorithm.
ind |
code_of_account |
account_description |
total_cost |
level |
supaccount |
review_status |
prn |
alg_name |
fun_unit |
variables |
|---|---|---|---|---|---|---|---|---|---|---|
1 |
2 |
User defined direct cost |
1000000000 |
0 |
Unchanged |
1 |
||||
2 |
21 |
User defined total cost 21 |
700000000 |
1 |
2 |
Unchanged |
0.7 |
|||
3 |
211 |
User defined total cost 211 |
100000000 |
2 |
21 |
Unchanged |
0.1 |
ud211 |
million |
v1, v2, v3 |
4 |
212 |
User defined total cost 212 |
200000000 |
2 |
21 |
Unchanged |
0.2 |
ud212 |
dollar |
v5, v8, v7 |
5 |
213 |
User defined total cost 213 |
400000000 |
2 |
21 |
Unchanged |
0.4 |
|||
7 |
2131 |
User defined total cost 2131 |
150000000 |
3 |
213 |
Unchanged |
0.15 |
ud2131 |
optional input |
v3, v2, v5 |
8 |
2132 |
User defined total cost 27 |
250000000 |
3 |
213 |
Unchanged |
0.25 |
ud2132 |
million |
v8, v4, v6 |
9 |
22 |
example account without algorithm |
300000000 |
2 |
22 |
Unchanged |
0.3 |
The raw_variable_automated_generated.csv file will be filled in by the user to provide the values of the variables used in the algorithm, the following columns are required:
var_value: value of the variable
var_unit: unit of the variable
ind |
var_name |
var_value |
var_unit |
var_alg |
var_need |
v_linked |
|---|---|---|---|---|---|---|
1 |
v1 |
REQUIRED |
REQUIRED |
|||
2 |
v2 |
REQUIRED |
REQUIRED |
|||
3 |
v3 |
REQUIRED |
REQUIRED |
|||
4 |
v4 |
REQUIRED |
REQUIRED |
|||
5 |
v5 |
REQUIRED |
REQUIRED |
|||
6 |
v6 |
REQUIRED |
REQUIRED |
|||
7 |
v7 |
REQUIRED |
REQUIRED |
|||
8 |
v8 |
REQUIRED |
REQUIRED |
If some variables are calculated from other variables, the user can fill in the algorithm name in the var_alg column, and the variables in the var_need column:
var_alg: algorithm associated with the variable if any
var_need: variables needed to calculate the variable if any
v_linked: superior variable if any
ind |
var_name |
var_value |
var_unit |
var_alg |
var_need |
v_linked |
|---|---|---|---|---|---|---|
1 |
v1 |
20 |
million |
v6 |
||
2 |
v2 |
50 |
million |
|||
3 |
v3 |
30 |
million |
v6 |
||
4 |
v4 |
2.5 |
km |
|||
5 |
v5 |
1500 |
m |
|||
6 |
v6 |
50 |
million |
ud_cal_v6 |
v1, v3 |
|
7 |
v7 |
50000000 |
dollar |
|||
8 |
v8 |
100000 |
$/m |
Fill in your own algorithm#
Save the filled in variable file as raw_variable.csv, run the command again to generate the algorithm table, databse sql file and the algorithm python file.
python ACCERT/src/scripts/gen_user_defined.py
The script will generate 3 files: - user_defined_algorithm.csv will a reference table. - user_defined_algorithm.sql will be used to create the database table. - user_defined_func.py will be used to calculate the total cost of each account or variable.
ind |
alg_name |
alg_for |
alg_description |
alg_python |
alg_formulation |
alg_units |
|---|---|---|---|---|---|---|
1 |
ud211 |
c |
description of ud211 optional |
user_defined_func |
formulation of ud211 optional |
million |
2 |
ud212 |
c |
description of ud212 optional |
user_defined_func |
formulation of ud212 optional |
dollar |
3 |
ud2131 |
c |
description of ud2131 optional |
user_defined_func |
formulation of ud2131 optional |
million |
4 |
ud2132 |
c |
description of ud2132 optional |
user_defined_func |
formulation of ud2132 optional |
million |
5 |
ud_cal_v6 |
v |
description of ud_cal_v6 optional |
user_defined_func |
formulation of ud_cal_v6 optional |
million |
This table will be used to create the database table. the column alg_for is the account or variable that the algorithm is applied to, c means the algorithm is applied to the account, v means the algorithm is applied to the variable. The alg_name is the name of the algorithm. The alg_unit is the unit of the algorithm function output.
And the user_defined_func.py file will be used to calculate the total cost of each account. User can modify the user_defined_func.py file to implement the algorithm. Each algorithm function will have the notes to explain the algorithm with the needed variables.
import numpy as np
from .Algorithm import Algorithm
class user_defined_func(Algorithm):
def __init__(self, ind, alg_name, alg_for, alg_description, alg_formulation, alg_units, variables, constants):
super().__init__(ind, alg_name, alg_for, alg_description, alg_formulation, alg_units, variables, constants)
def run(self, inputs: dict) -> float:
"""
Executes the algorithm specified by the name in the instance variables.
Parameters:
inputs (dict): Dictionary of input variables required for the algorithm.
Returns:
float: Result of the algorithm computation.
"""
# run the algorithm using self.name not self.alg_name
return self._run_algorithm(self.name, [inputs[var.strip()] for var in self.variables.split(",") if var.strip()])
def _run_algorithm(self, alg_name: str, variables: list) -> float:
"""
Runs the specified algorithm with given variables.
Parameters:
alg_name (str): The name of the algorithm to run.
variables (list): List of input variables for the algorithm.
Returns:
float: Result of the algorithm computation.
"""
try:
algorithm = getattr(self, alg_name)
return algorithm(*variables)
except AttributeError:
raise ValueError(f"Algorithm {{alg_name}} not found")
@staticmethod
# ud211: description of ud211 optional
def ud211(v1, v2, v3):
# TODO: Implement the logic for ud211
# The output unit should be million
pass
@staticmethod
# ud212: description of ud212 optional
def ud212(v5, v8, v7):
# TODO: Implement the logic for ud212
# The output unit should be dollar
pass
@staticmethod
# ud2131: description of ud2131 optional
def ud2131(v3, v2, v5):
# TODO: Implement the logic for ud2131
# The output unit should be million
pass
@staticmethod
# ud2132: description of ud2132 optional
def ud2132(v8, v4, v6):
# TODO: Implement the logic for ud2132
# The output unit should be million
pass
@staticmethod
# ud_cal_v6: description of ud_cal_v6 optional
def ud_cal_v6(v1, v3):
# TODO: Implement the logic for ud_cal_v6
# The output unit should be million
pass
After filled in the algorithm function, it should be saved as user_defined_func.py in the same directory. Here is an example of the filled in algorithm function.
import numpy as np
from .Algorithm import Algorithm
class user_defined_func(Algorithm):
def __init__(self, ind, alg_name, alg_for, alg_description, alg_formulation, alg_units, variables, constants):
super().__init__(ind, alg_name, alg_for, alg_description, alg_formulation, alg_units, variables, constants)
def run(self, inputs: dict) -> float:
"""
Executes the algorithm specified by the name in the instance variables.
Parameters:
inputs (dict): Dictionary of input variables required for the algorithm.
Returns:
float: Result of the algorithm computation.
"""
# run the algorithm use self.name not self.alg_name
return self._run_algorithm(self.name, [inputs[var] for var in self.variables.split(",")])
def _run_algorithm(self, alg_name: str, variables: list) -> float:
"""
Runs the specified algorithm with given variables.
Parameters:
alg_name (str): The name of the algorithm to run.
variables (list): List of input variables for the algorithm.
Returns:
float: Result of the algorithm computation.
"""
try:
algorithm = getattr(self, alg_name)
return algorithm(*variables)
except AttributeError:
raise ValueError(f"Algorithm {alg_name} not found")
@staticmethod
#ud211: User defined total cost 211
def ud211(v1, v2, v3):
return v1 + v2 + v3
@staticmethod
#ud212: User defined total cost 212
def ud212(v5, v8, v7):
some_calc = v5 * v8 + v7
return some_calc
@staticmethod
#ud2131: User defined total cost 2131
def ud2131(v3, v2, v5):
some_var = v2 - v3
other_var = some_var/200
total_cost = other_var * v5
return total_cost
@staticmethod
#ud2132: User defined total cost 2132
def ud2132(v8, v4, v6):
if v6 > 52:
return v4*v8/999
else:
return v4*v8/1000
@staticmethod
#ud_cal_v6: User defined calculation for v6
def ud_cal_v6(v1, v3):
return v1 + v3
Create the database table#
In the same folder a user_defined_algorithm.sql file will be generated. Run the following command to implement all the tables in the database.
python ACCERT/src/scripts/run_sql.py
The script will create the database table and insert the data from the user_defined_account.csv, user_defined_variable.csv and user_defined_algorithm.csv files into the database.
You can also run mysql command and source the user_defined_algorithm.sql file to create the database table.
$ mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2475
Server version: 8.0.27 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>source user_defined_algorithm.sql
Prepare the input file#
After the database table is created, you can start preparing the input file for your user-defined reference model. The input file should be in the son format. Run the following command to make changes to ACCERT schema to accept the user-defined reference model.
python ACCERT/src/scripts/prepared_input.py
The script will generate a list of accepted values for the user-defined reference model. The user can fill in the input file with the accepted values. The input file should be in the son format. Here is an example of the input file.
% ACCERT Test input file
% Author: J. Zhou (jia.zhou@anl.gov)
% Last updated: 08/08/2024
accert{
ref_model = "user_defined"
% variables can be assigned at top level
var( v3 ){ value = 29 unit = million }
l0COA(2){
l1COA(21){
l2COA(212){
total_cost{value = 201 unit = million}
}
}
}
}
Run your own reference model#
After the input file is prepared, you can run the reference model with the following command.
python ACCERT/src/Main.py -i user_defined_input.son
The script will generate the output file in the same directory. The output file will be in the son format. Here is an example of the output file, that just created.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::'###:::::'######:::'######::'########:'########::'########:
::'## ##:::'##... ##:'##... ##: ##.....:: ##.... ##:... ##..::
:'##:. ##:: ##:::..:: ##:::..:: ##::::::: ##:::: ##:::: ##::::
'##:::. ##: ##::::::: ##::::::: ######::: ########::::: ##::::
#########: ##::::::: ##::::::: ##...:::: ##.. ##:::::: ##::::
##.... ##: ##::: ##: ##::: ##: ##::::::: ##::. ##::::: ##::::
##:::: ##:. ######::. ######:: ########: ##:::. ##:::: ##::::
..:::::..:::.......::::......::........::..:::::..:::::..:::::
======================================== Reading user input ========================================
[USER_INPUT] Reference model is "user_defined"
WARNING: No power input found in the user input file
[Updating] Variable v3
[Updated] Changed from 30.0 million to 29.0 million
[Updating] Sup Variable v6, running algorithm: [ud_cal_v6],
[Updating] with formulation: formulation of ud_cal_v6 optional
[Updated] Reference value is : 5.00e+01 million, calculated value is: 4.90e+01 million
=================================Extracting user changed variables==================================
+----------+-----------------------------+-----------+----------+
| var_name | var_description | var_value | var_unit |
+----------+-----------------------------+-----------+----------+
| v3 | description of v3 optional | 29.00 | million |
| v6 | description of v6 optional | 49.00 | million |
+----------+-----------------------------+-----------+----------+
====================================Extracting affected accounts====================================
variable "v3" affects account(s):
211, 2131
variable "v6" affects account(s):
2132
======================================== Updating accounts =========================================
[Updating] Account [211], running algorithm: [ud211],
[Updating] with formulation: formulation of ud211 optional
[Updating] Total cost of account 211
[Updated] Changed from 100,000,000.00 dollar to 99,000,000.00 dollar
[Updating] Account [2131], running algorithm: [ud2131],
[Updating] with formulation: formulation of ud2131 optional
[Updating] Total cost of account 2131
[Updated] Changed from 150,000,000.00 dollar to 157,500,000.00 dollar
[Updating] Account [2132], running algorithm: [ud2132],
[Updating] with formulation: formulation of ud2132 optional
[Updating] Total cost of account 2132
[Updated] Changed from 250,000,000.00 dollar to 250,000,000.00 dollar
========================================== IMPORTANT NOTE ==========================================
Some cost have changed by user inputs and may not be reflected correctly in the cost elements table.
[Updating] Total cost of account 212
[Updated] Changed from 200,000,000.00 dollar to 201,000,000.00 dollar
===================================== Rolling up account table =====================================
[Updating] Rolling up account table from level 4 to level 3
[Updating] Rolling up account table from level 3 to level 2
[Updating] Rolling up account table from level 2 to level 1
[Updating] Rolling up account table from level 1 to level 0
[Updated] Account table rolled up
=============================== Generating results table for review ================================
+-----------------+-----------------------------------+------------+-------+---------------+
| code_of_account | account_description | total_cost | level | review_status |
+-----------------+-----------------------------------+------------+-------+---------------+
| 2 | User defined direct cost | 1,007.50 | 0 | Updated |
| 21 | User defined total cost 21 | 707.50 | 1 | Updated |
| 211 | User defined total cost 211 | 99.00 | 2 | User Input |
| 212 | User defined total cost 212 | 201.00 | 2 | User Input |
| 213 | User defined total cost 213 | 407.50 | 2 | Updated |
| 2131 | User defined total cost 2131 | 157.50 | 3 | User Input |
| 2132 | User defined total cost 27 | 250.00 | 3 | User Input |
| 22 | example account without algorithm | 300.00 | 1 | Unchanged |
+-----------------+-----------------------------------+------------+-------+---------------+
Successfully created excel file user_defined_updated_account.xlsx