Try   HackMD

Running COSMOSS from the workspace

In this tutorial, I will layout a step-by-step process about how to run COSMOSS from workspace (command line mode). One of the major benefits is to run it in a batch mode. Running in batch mode allows one to explore the "change" from some acting variables. For example, given two molecules, if you want to know how would spectral features change when you pull them away, you can run simulations in a for-loop instead of laborious mouse-clickings. Even better is that you can visualize the result as a movie!

Objective:
Generating the movie of FTIR spectral change while pulling two molecules away from 3 to 7.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Constructing the TCO model

Before we start, make sure you've already run COSMOSS at least once so all the paths to relevant function are set!

This tutorial works for version v2.3.2 and newer, so update your COSMOSS before start.

To generate a structure model, COSMOSS call the model constructors when you click on the Generate button from the Model_GUIs. In this example, we are constructing the classic TCO model and the corresponding constructor function is defined in the 'ConstructTCO.m' in the following path:

.../MoleculeConstruction/TCO/

Side note: To figure out what exactly the Generate button of the 'Model_TCO' is doing, Let's dig into the Button_GeneratePushed function of the 'Model_TCO.mlapp':

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

To view/edit the GUIs, please see the tutorial on How to edit COSMOSS GUIs.

Here is the first few lines of the ConstructTCO.m:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

To construct a TCO model, one needs to provide one input argument only: GUI_Inputs. The GUI_Inputs is a Matlab structure array collecting a bunch of name/value pairs (don't be confused, the structure array has nothing to do with the 3D structure we are constructing here!).

Note that there is an Input Parser section determines if the required inputs( in this case, the fields of the GUI_Inputs ) were provided. If a required field were missing, a default value will be assigned to the GUI_Inputs so all the necessary fields will be ready before running any meaningful codes below. For example, if the Displacement field is missing in the GUI_Inputs, the defaultDisplacement will be assigned to the GUI_Inputs so that

>> GUI_Inputs.Displacement

ans =

     0     0     5

One more important remark about the Input parser section:
Almost every functions in COSMOSS have an Input parser section. The list of the Inputs fields give you an idea about what are possible parameters one can safely play around. The section acts sort of like an Application Programming Interface. And it is useful for debugging without figuring out what are necessary variables to run an interested code.

In this example, I want to place the two molecule at 3 away on the X axis. I also want to tilt each of them 30 degrees away from the Z axis, in opposite directions, so that the FTIR peaks split (i.e. 2 peaks!). To define such orientation, I can construct an empty structure array, named GUI_Inputs and fill-in all the necessary fields:

GUI_Inputs = struct;
GUI_Inputs.Displacement = [3,0,0];
GUI_Inputs.Theta_D1 = -30;
GUI_Inputs.Theta_D2 = 30;

Running the ConstructTCO function with the prepared 'GUI_Inputs' will results in a StructureData Class, here I named SD_TCO.

SD_TCO = ConstructTCO(GUI_Inputs);

One can verify the generated structure with the SD_Draw method:

SD_TCO.SD_Draw;

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Simulate the FTIR spectra

Now we have a model structure (SD_TCO), let's take a look at the Main_GUI to see what will happen if I click on the FTIR button?

>> appdesigner COSMOSS

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

The first thing it does is use the CheckStructue() function to see if a model structure exist in the main GUI:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

The following 4 lines deal with other GUI related works (i.e. not important for our purpose):

app.RefreshSource = 'FTIR'; % Identify source if trigger
RefreshOff(app)             % Turn off the auto-refresh tag for FTIR

% Switch the experimental setting panel on the Main_GUI to 1D tab
app.TabGroup.SelectedTab = app.DTab_Exp1D; 
app.TabGroupTools.SelectedTab = app.Tab_FTIR; 

Note: all of the above are not relevant to run simulation in the command line mode. Don't worry if you don't understand.

The only relevant code is this one:

app.Data_FTIR = OneD_Iteration(@FTIR_Main,app);

This line assigns the output of the OneD_Iteration function as the Data_FTIR field in the Main_GUI. The input of the OneD_Iteration function takes the function handle of FTIR simulation code, named @FTIR_Main and pass the GUI related data by the variable app

The OneD_Iteration function deals with the ensemble average of the one-dimensional spectrum( i.e. FTIR and SFG ), which will be detailed in another tutorials. Here we only care about what it does without the ensemble average:

function OneD = OneD_Iteration(h1DFunc,app)
I = app.Parse_GUI;
S = app.Structure;
...

if eq(I.Sampling,1)
    ...
    % Codes deal with the ensemble average, which we neglect.%
    ...
else
    OneD = h1DFunc(S,I); % call the 1D spectral simulation function
    Plot1D(hAx,OneD,I);  % draw the spectra
end

What OneD_Iteration really does is call the simulation function FTIR_Main and providing two inputs: S(Model structure) and I (GUI inputs on the Main_GUI) for the FTIR_Main.

Since there is another Input parser section in the Main_GUI taking care of the default inputs (see 'Parse_GUI()' function in the COSMOSS.mlapp file for details), and we just generated the TCO model (SD_TCO), we can simply run the code as follow:

OneD = FTIR_Main(SD_TCO,GUI_Inputs);

The output variable OneD contains information for drawing the spectra. We just need to provide a handle of a figure axes for the Plot1D to work:

hF  = figure;
hAx_FTIR = axes('Parent',hF);

Plot1D(hAx_FTIR,OneD,GUI_Inputs);

Voila, here is your FTIR spectra!
Wait But, it doesn't looks quite right since I am expecting two peaks

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Seems like my x range may not be correct. Let's check what are the possible inputs in the Plot1D function to correct this error:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Let's change the default vales by adding the 'FreqRange' field to the GUI_Input and regenerate the SD_TCO. Here is the code puts everything together:

GUI_Inputs = struct;
GUI_Inputs.Theta_D1 = -30;
GUI_Inputs.Theta_D2 = 30;
GUI_Inputs.FreqRange = 1650:1800;

SD_TCO = ConstructTCO(GUI_Inputs);

hF  = figure;
hAx_FTIR = axes('Parent',hF);

Plot1D(hAx_FTIR,OneD,GUI_Inputs);

Finally, here is the correct spectra!!!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

You may wonder where is the local mode frequency defined?
Hint: Try to read the ConstructTCO.m and you will find it calls SD_1ExH() function to generate the one-exciton Hamiltonian of the system. You might want to check the input parser section 😁.

Scanning the distance

With previous sections, we know how to simulate a FTIR spectra for the model TCO at a specific configuration. In order to make a movie of FTIR spectral change when the two molecules pulling apart, we need to simulate all the configurations and save them as movie frames.

Let's prepare an array (distanceArray) and run a for-loop by substituting the X distance between the two molecules for the simulations. Also, we will need to provide some figure/axes setting so the molecule structure and the corresponding FTIR spectra will be presented side-by-side. Finally, the figures will be saved as an array of movies frames (Frame_all) waiting for further inspection.

%% Setup scanning parameters
distanceArray = 3:0.1:7;

GUI_Inputs = struct;
GUI_Inputs.Theta_D1 = -30;
GUI_Inputs.Theta_D2 = 30;
GUI_Inputs.FreqRange = 1650:1800;

% figure setting
hF  = figure;
hF.Position = [100,100,800,300];
hAx_FTIR     = subplot(1,2,1,'Parent',hF);
hAx_Molecule = subplot(1,2,2,'Parent',hF);

%% Structure generation, simulation, and make figure
for i = 1:length(distanceArray)
    
    % clear the axises before start
    cla(hAx_FTIR)
    cla(hAx_Molecule)
    
    % Prepare initial structure
    GUI_Inputs.Displacement = [distanceArray(i),0,0];
    SD_TCO = ConstructTCO(GUI_Inputs);

    % Run the Spectral simulation
    OneD = FTIR_Main(SD_TCO,GUI_Inputs);

    % make figure
    Plot1D(hAx_FTIR,OneD,GUI_Inputs);
    SD_Draw(SD_TCO,hAx_Molecule);
    hAx_Molecule.XLim = [-6,6];
    
    drawnow % force to update figure before the for-loop is finished
    Frame_all(i) = getframe(hF);
    
end 

Generating the GIF

Now we are ready to play back the movie frames by generate the same figure settings:

%% Play movie frames
hF  = figure;
hF.Position = [100,100,800,300];
hAx_FTIR     = subplot(1,2,1,'Parent',hF);
hAx_Molecule = subplot(1,2,2,'Parent',hF);
movie(hF,Frame_all,10) % play the movie for 10 times

Voila! The movie succesully capture the two extreme from strongly coupled case with two distictive peaks to nearly non-coupled case where the two peaks merge as one.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

To save the movie as a GIF, we need to convert the movie frames to images (frame2im & rgb2ind)and write it as a image sequence. Here I provide an example code for it:

%% Save GIF
saveGIF  = 1;
BaseFileName = 'TCO_X3_X10';
SavePath = '~/Desktop';
SaveName = [SavePath,'/',BaseFileName,'.gif'];
DT = 0.1;

if saveGIF
    for j = 1:length(distanceArray)

        frame = Frame_all(j);
        im = frame2im(frame);
        [imind,cm] = rgb2ind(im,256);

        if j == 1
          imwrite(imind,cm,SaveName,'gif','Loopcount',inf,'DelayTime',DT);
        else
          imwrite(imind,cm,SaveName,'gif','WriteMode','append','DelayTime',DT);
        end

    end
    disp([BaseFileName, 'GIF saved...'])
end

The flow chart of the code

Final remark: The same workflow can be easily adapt for different purposes. Once you understand how to find the necessary parameters for an interested function, you can call the function through the workspace how ever you like. This is an essential ability for testing/debugging COSMOSS.

Created with Raphaël 2.2.0startSet initial parametersModify modelSimulate spectrumFinished?Save GIFyesno

The full example code

Here is the code after we put everything together (tested and run after version v2.3.2):

%% Setup canning parameters
distanceArray = 3:0.1:7;

GUI_Inputs = struct;
GUI_Inputs.Theta_D1 = -30;
GUI_Inputs.Theta_D2 = 30;
GUI_Inputs.FreqRange = 1650:1800;

% figure setting
hF  = figure;
hF.Position = [100,100,800,300];
hAx_FTIR     = subplot(1,2,1,'Parent',hF);
hAx_Molecule = subplot(1,2,2,'Parent',hF);

%% Strueture generation, simulation, and make figure
for i = 1:length(distanceArray)
    
    % clear the axises before start
    cla(hAx_FTIR)
    cla(hAx_Molecule)
    
    % Prepare initial structure
    GUI_Inputs.Displacement = [distanceArray(i),0,0];
    SD_TCO = ConstructTCO(GUI_Inputs);

    % Run the Spectral simulation
    OneD = FTIR_Main(SD_TCO,GUI_Inputs);

    % make figure
    Plot1D(hAx_FTIR,OneD,GUI_Inputs);
    SD_Draw(SD_TCO,hAx_Molecule);
    hAx_Molecule.XLim = [-6,6];
    
    drawnow
    Frame_all(i) = getframe(hF);
    
end 

%% Save GIF
saveGIF  = 1;
BaseFileName = 'TCO_X3_X10';
SavePath = '~/Desktop';
SaveName = [SavePath,'/',BaseFileName,'.gif'];
DT = 0.1;

if saveGIF
    for j = 1:length(distanceArray)

        frame = Frame_all(j);
        im = frame2im(frame);
        [imind,cm] = rgb2ind(im,256);

        if j == 1
          imwrite(imind,cm,SaveName,'gif','Loopcount',inf,'DelayTime',DT);
        else
          imwrite(imind,cm,SaveName,'gif','WriteMode','append','DelayTime',DT);
        end

    end
    disp([BaseFileName, 'GIF saved...'])
end

%% Play movie frames
hF  = figure;
hF.Position = [100,100,800,300];
hAx_FTIR     = subplot(1,2,1,'Parent',hF);
hAx_Molecule = subplot(1,2,2,'Parent',hF);
movie(hF,Frame_all,10)
tags:tutorials COSMOSS