What @Amiramix states is accurate, but it's not the whole picture.
There's a low-coupling mechanism to communicate events between modules in ejabberd - it's the hooks and handlers concept. The link points at MongooseIM documentation, but this mechanism is more or less the same in both codebases.
In general, one module can call a hook, which is alike a function call, but depending on the registered handlers may or may not result in some action(s) being carried out. Other modules can register handlers for hooks they choose. If you're authoring the modules in question, this is a mechanism which might give you the required communication channel.
To make things more concrete - each time mod_filter needs some information that only mod_calculate has access to, it can run ejabberd_hooks:run_fold/4 with a custom hook name. If mod_calculate registers a handler for that hook (usually in its start function), it can return some data relevant to mod_filter. However, different modules can implement a handler for the hook, so mod_filter and mod_calculate aren't coupled as they would be if you used a direct function call (like mod_calculate:some_function(...)).