# Experiments
This is a guide to run the experiments proposed in _"A Neuro-symbolic Approach to Inverse Design of Thin-layer Metamaterials Under Layout Constraints", Anonymous Authors_

## Content
- Setup
- 5 Layer Metamaterials Dataset Experiments
- 10 Layer Metamaterials Dataset Experiments

---

# Setup
This implementation can be executed in Linux taking advantage of the Anaconda3 virtual environments.
All the experiments can run inside the same environment, which can be instantiated as follows.

Run the following commands from terminal in order to create the virtual environment (**Requirement**: Anaconda3 installed):

```
chmod +x env.sh
./env.sh env_name
```

## <tt>N<sub>F</sub></tt> and <tt>N<sub>F</sub>'</tt> modules training
Due to space costraints it was not possible to include the pre-trained model of <tt>N<sub>F</sub></tt> and <tt>N<sub>F</sub>'</tt> for both datasets. 

Thus <tt>N<sub>F</sub></tt> should be trained using the scripts `dataset_5_layer/running_scripts/simulator/train_simulator.ipynb` and `dataset_10_layer/src/running_scripts/simulator_train.ipynb`.

<tt>N<sub>F</sub>'</tt>, instead, through the scripts `dataset_5_layer/running_scripts/vae/vae_train.ipynb` and `dataset_10_layer/src/running_scripts/vae_train.ipynb`.

Once trained models will be available in the `trained_models` directory within each Dataset folder.

## Pre-trained models
Pre-trained models (e.g. autoencoders), exept from <tt>N<sub>F</sub></tt> and <tt>N<sub>F</sub>'</tt>,  are available in the `trained_models` directory within each Dataset folder. These models can be used to quickly start experiments without the need for retraining. 
The models can be re-trained using the scripts in the folders `dataset_5_layer/running_scripts` and `dataset_10_layer/src/scripts`. Each methods has its own subfolder with the necessary code.

## How to apply diverse Layout Costraints

The semantic loss is implemented using the `semantic_loss_pytorch` library. The formula and Vtree are generated within each experiment script.
The `commons/semantic_loss.py` module provides helper functions to construct the logical formula and the Vtree.
Specifically, the `construct_vars` function creates the boolean variables, and the other functions define the constraints.
To compare the methods across the **different layout constraint** presented in the main manuscript, a function (based on the chosen constraint)  must be chosen from in `commons/semantic_loss.py` and assigned to the `formula` variable. The generated formula and Vtree are saved as `.sdd` and `.vtree` files, respectively, which are then used by the `SemanticLoss` class.For example, to select the layout constraint PAL2:
```python
# Specify the number of layer and materials of the dataset
n_layer = 5
n_layer = 5

# Construct the variables x_i_j that represent an assignment of material m_j to a layer i
x, manager, vtree = semloss.construct_vars(n_layer, n_mat)

# Specify the filename for the vtree and sdd
formula_str = 'formula.sdd'
vtree_str = 'order.vtree'

# Construct the constraint formula by using the helper functions aforementioned
formula = semloss.force_palindrome_material(x, n_lay, n_mat, up_to=2)

# Compile the sdd and store it by using the SddManager class
manager.save(formula_str.encode(), formula)
vtree.save(vtree_str.encode())

# Finally, instantiate the semantic loss by passing as arguments the filename of the .sdd and .vtree file
sloss = SemanticLoss(formula_str, vtree_str)
```

In order to simplify the execution, we introduced a variable that automatically choose the corresponding count and constraint function. It is sufficient to change this variable as in the following to change layout constraint:

`
experiment_loss = semloss.SemanticExperiment.PERIODIC_2
`

By default, the NA and VAE-id scripts will execute the model both with and without semantic loss. Since the no-loss results are the same for every layout constraint it is sufficient to execute them once and then comment out the lines that invoke the model. Also, those models run on cuda-capable devices. Gidnet, since it executes the T computations sequentially, is run on cpu, launching one material on each cpu core. Additionally, the gidnet script only execute the model with or without semantic loss. Every script execute the experiments **only for the selected layout costraint** and save the results in the relative csv file. 
The experiments scripts generally save the logs in a subfolder `logs/*`, which is the same directory where the plots notebook search for the corresponding `log.csv` file.

In order to try different constraint function, you must:
- open the `*_experiments.py` file and change the lines related to the semantic loss, as explained earlier. Generally, it is sufficient to change the parameter `experiment_loss`
- Launch the script and check that the `*.csv` are correctly placed in `logs/` folder


---

# 5 Layer Metamaterials Dataset Experiments

## Dataset
The dataset can be generated by running the `generate_data_tmm.ipynb` notebook in the `dataset_5_layer/data_utils` directory.
This will generate the `.h5` files containing the structures and their associated responses.

```
cd dataset_5_layer/data_utils
ipython generate_data_tmm.ipynb
```
## Implementation
The code for these experiments can be found into the folder `dataset_5_layer`.
This folder contains:
- the `data_utils` folder which collects:
  - the generator script `generate_data_tmm.ipynb` by [Lininger et al., 2021], as well as all the python modules for applying the transfer matrix method.
  - the `data` folder which collects all the `.h5` datasets (this is the destination path for the generator). 
  
- the `configs` folder which collects:
  - a file `config.py` which specify the absolute path of the `dataset_5_layer` folder.
  - a configuration file `gidnet.yaml` to setup the parameter within the GIDnet architecture in the associated experiments script.
  - a configuration files `metamaterials.yaml` to setup parameters regarding Materials, Spectral response, and Dataset.
  
- the `experiments` folder which collects:
  - a subfolder for each method (GIDnet, VAE-ID and Neural Adjoint) contaning: a script for running the experiments called `*_experiments.py` and a script for plotting the results called `plots_*.ipynb`
  - the subfolder `dataset_evaluation` containing the scripts `counts.ipynb` and `timings.ipynb`, that can be used to obtain the results , respectively, reported in Table 2 inside the Main paper and in Table 1 inside the Supplementary Material.

- the `base_model` folder which collects the code for <tt>E</tt>, <tt>D</tt>, and the <tt>N<sub>F</sub></tt> 

- the `methods` folder which collects the code regarding the implementation of the compared methods (GIDnet, VAE-ID and Neural Adjoint)

- the `running_scripts` folder which contains the code to re-train <tt>E</tt>, <tt>D</tt>, <tt>N<sub>F</sub></tt>, and VAE-ID
  
## Run


To run the experiments with and without semantic loss, execute:
```
cd dataset_5_layer/experiments/<method>
python <method>_experiments.py
```

## Results
The plots to visualize the results of the experiments can be generated by running the associated script in each method's folder. Prior to the execution, change the constraint variable to match the one you are doing analysis on
- **GIDnet:** `dataset_5_layer/experiments/gidnet/plots_gidnet.ipynb`
- **Neural Adjoint:** `dataset_5_layer/experiments/adjoint/plots_adjoint.ipynb`
- **VAE-ID:** `dataset_5_layer/experiments/vae/plots_vae.ipynb`
---

# 10 Layer Metamaterials Dataset Experiments
## Dataset
The source of the 10 layer dataset can be found in the original work by [Yang et al., 2023] as indicated in the main manuscript. It should be placed in a folder called `dataset_10_layer/data`


## Implementation
The code for these experiments can be found into the folder `dataset_10_layer/src`.
This folder contains:
  - the `assets` folder which contains the material properties and the code of the tmm simulator
  
  - the `dataset_evaluation` folder which contains the scripts `counts.ipynb` and `timings.ipynb`, that can be used to obtain the results , respectively, reported in Table 2 inside the Main paper and in Table 1 inside the Supplementary Material.

  - the `utils` folder which contains utilities functions used, for example, to load the dataset or to plot the spectral response chart. **IMPORTANT**: prior to the execution, you must update the PATH_TO_DATA variable in `utils/data.py`

  - the `running_scripts` folder which contains the script used for training the methods VAE-ID (and the simulator <tt>N<sub>F</sub>'</tt>), Neural Adjoin and <tt>N<sub>F</sub></tt>.

  - a folder for each method (GIDnet, VAE-ID and Neural Adjoint) contaning: a script for running the experiments called `*_experiments.py` and a script for plotting the results called `plots_*.ipynb`

  - the `models` folder which collects the code for <tt>E</tt>, <tt>D</tt>, <tt>N<sub>F</sub></tt> and  the compared methods (GIDnet, VAE-ID and Neural Adjoint)
## Run 

To run the experiments with and without semantic loss, execute:
```
cd dataset_10_layer/src/experiments_<method>
python <method>_experiments.py
```
The script will execute the model with and without the semantic loss **only for the selected layout costraint** and save the results in two separate CSV files. 


## Results
The plots to visualize the results of the experiments can be generated by running the associated notebook in each method's folder.
- **GIDNet:** `dataset_10_layer/src/experiments_gidnet/gidnet_plots.ipynb`
- **Adjoint Method:** `dataset_10_layer/src/experiments_adjoint/plots_adjoint.ipynb`
- **VAE-based Method:** `dataset_10_layer/src/experiments_vae/vae_plots.ipynb`
