ROOT logo
#include "ARVersion.h"
#if !defined(__CINT__) || defined(__MAKECINT__)
#include "AliCDBManager.h"
#include "AliCDBStorage.h"
#include "AliCDBId.h"
#include "AliCDBMetaData.h"
#include "AliGeomManager.h"
#include "AliMC.h"
#include <TROOT.h>
#include "AliRun.h"
#include <TGeoManager.h>
#include <TString.h>
#include <TInterpreter.h>
#include "iostream"
#include "fstream"
using namespace std;
#endif

Bool_t DiffGeomBeforeTagging(const char* recipient, const char* cdbUri="local://$ALICE_ROOT/OCDB", const char* cfgFile="$ALICE_ROOT/macros/Config.C"){
	// Compare the geometry created in the current AliRoot with the one
	// in the OCDB directory of the current aliroot. If they differ,
        // warn the recipients to update the geometry in $ALICE_ROOT/OCDB
        // before tagging and to consider updating it in the raw OCDB.
        //
        // Running this macro always before creating a release tag will
        // allow to have in release tags OCDBs the geometry corresponding
        // to their code.
        //
        // The recipient string is supposed to contain comma-separated 
        // valid email addresses, at least the one of the librarian and
        // probably also the one of the guy in charge of the geometry object.
        //

        // Uplaod the geometry from $ALICE_ROOT/OCDB and get the number of nodes
	AliCDBManager* cdb = AliCDBManager::Instance();
	cdb->SetDefaultStorage(cdbUri);
        cdb->Get("GRP/Geometry/Data",0);
        Int_t svnocdb_nnodes = gGeoManager->GetNNodes();
        Printf("The geometry in OCDB has %d nodes",svnocdb_nnodes);
	cdb->SetRun(0);

	gGeoManager = 0;

        // Create the geometry and get the number of nodes
	if(!gSystem->AccessPathName("geometry.root")){
		Printf("Deleting existing \"geometry.root\"");
		gSystem->Exec("rm -rf geometry.root");
	}

	gROOT->LoadMacro(cfgFile);
	gInterpreter->ProcessLine(gAlice->GetConfigFunction());
	gAlice->GetMCApp()->Init();

	if(!gGeoManager){
		Printf("Unable to produce a valid geometry to be put in the CDB!");
		return kFALSE;
	}

	if(gSystem->AccessPathName("geometry.root")){
		Printf("Did not find freshly written \"geometry.root\" file. Exiting ...");
		return kFALSE;
	}

	Printf("Reloading freshly written geometry.root file");
        if (TGeoManager::IsLocked()) TGeoManager::UnlockGeometry();
        AliGeomManager::LoadGeometry("geometry.root");

        Int_t svncode_nnodes = gGeoManager->GetNNodes();
        Printf("The generated geometry has %d nodes",svncode_nnodes);

        // If the number of nodes differs, remove the geometry file from the local OCDB
        // and replace it by calling the UpdateCDBIdealGeom.C macro
        if (svncode_nnodes != svnocdb_nnodes){
                Printf("The geometry generated and the one in the current OCDB differ.");
                Printf("Remove \"$ALICE_ROOT/OCDB/GRP/Geometry/Data/Run0_999999999_v0_s0.root\".");
                Printf("and run $ALICE_ROOT/GRP/UpdateCDBIdealGeom.C(\"local://$ALICE_ROOT/OCDB\",%s)",cfgFile);

		// Get root and AliRoot versions
		const char* rootv = gROOT->GetVersion();
		TString av(ALIROOT_BRANCH);
		TString revnum(ALIROOT_REVISION);
		Printf("root version: %s.  AliRoot %s, revision number %s",rootv,av.Data(),revnum);

		// create and send mail
		TString subject(Form("AliRoot revision %d is about to be tagged and the geometry changed!",revnum));
                // mail body 
                TString bodyFileName("mailbody.txt");
               // bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
                gSystem->ExpandPathName(bodyFileName);

                ofstream mailBody;
                mailBody.open(bodyFileName, ofstream::out);

                if (!mailBody.is_open())
                {
                        Printf("Could not open mail body file %s", bodyFileName.Data());
                        return kFALSE;
                }

                TString recipients(recipient);

                TString body;
                body = Form("Dear AliRoot librarian or geometry expert,\n\n");
                body += Form("while tagging the current revision - r%d - the geometry produced by the code\n"
                                "appears to have changed w.r.t. to the one saved at the previous tag.\n\n"
				"You should remove \"$ALICE_ROOT/OCDB/GRP/Geometry/Data/Run0_999999999_v0_s0.root\"\n"
				"and run $ALICE_ROOT/GRP/UpdateCDBIdealGeom.C(\"local://$ALICE_ROOT/OCDB\",%s) "
				"before tagging.\n\n"
                                "Also consider updating the raw geometry on the raw OCDB.\n\n"
				"Je vous prie de bien vouloir croire en l'assurance de mes respectueuses et honorables salutations.",revnum,cfgFile);
		mailBody << body.Data();
		mailBody.close();

		Printf("Sending mail to \"%s\"",recipients.Data());
		TString mailCommand("");
                if(recipients.CountChar(',')==0){
                        mailCommand = Form("mail -s \"%s\" %s < %s",
                                        subject.Data(),
                                        recipients.Data(),
                                        bodyFileName.Data());
                }else{
                        TString cc(recipients);
                        recipients.Remove(recipients.First(','));
                        cc.Replace(0,cc.First(',')+1,"");
                        mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
                                        subject.Data(),
                                        cc.Data(),
                                        recipients.Data(),
                                        bodyFileName.Data());
                }

                Bool_t result = gSystem->Exec(mailCommand.Data());
		return result;
        }else{
                Printf("There are no changes between the geometry generated with current code and the one in the current OCDB.");
        }
	return kTRUE;
}

 DiffGeomBeforeTagging.C:1
 DiffGeomBeforeTagging.C:2
 DiffGeomBeforeTagging.C:3
 DiffGeomBeforeTagging.C:4
 DiffGeomBeforeTagging.C:5
 DiffGeomBeforeTagging.C:6
 DiffGeomBeforeTagging.C:7
 DiffGeomBeforeTagging.C:8
 DiffGeomBeforeTagging.C:9
 DiffGeomBeforeTagging.C:10
 DiffGeomBeforeTagging.C:11
 DiffGeomBeforeTagging.C:12
 DiffGeomBeforeTagging.C:13
 DiffGeomBeforeTagging.C:14
 DiffGeomBeforeTagging.C:15
 DiffGeomBeforeTagging.C:16
 DiffGeomBeforeTagging.C:17
 DiffGeomBeforeTagging.C:18
 DiffGeomBeforeTagging.C:19
 DiffGeomBeforeTagging.C:20
 DiffGeomBeforeTagging.C:21
 DiffGeomBeforeTagging.C:22
 DiffGeomBeforeTagging.C:23
 DiffGeomBeforeTagging.C:24
 DiffGeomBeforeTagging.C:25
 DiffGeomBeforeTagging.C:26
 DiffGeomBeforeTagging.C:27
 DiffGeomBeforeTagging.C:28
 DiffGeomBeforeTagging.C:29
 DiffGeomBeforeTagging.C:30
 DiffGeomBeforeTagging.C:31
 DiffGeomBeforeTagging.C:32
 DiffGeomBeforeTagging.C:33
 DiffGeomBeforeTagging.C:34
 DiffGeomBeforeTagging.C:35
 DiffGeomBeforeTagging.C:36
 DiffGeomBeforeTagging.C:37
 DiffGeomBeforeTagging.C:38
 DiffGeomBeforeTagging.C:39
 DiffGeomBeforeTagging.C:40
 DiffGeomBeforeTagging.C:41
 DiffGeomBeforeTagging.C:42
 DiffGeomBeforeTagging.C:43
 DiffGeomBeforeTagging.C:44
 DiffGeomBeforeTagging.C:45
 DiffGeomBeforeTagging.C:46
 DiffGeomBeforeTagging.C:47
 DiffGeomBeforeTagging.C:48
 DiffGeomBeforeTagging.C:49
 DiffGeomBeforeTagging.C:50
 DiffGeomBeforeTagging.C:51
 DiffGeomBeforeTagging.C:52
 DiffGeomBeforeTagging.C:53
 DiffGeomBeforeTagging.C:54
 DiffGeomBeforeTagging.C:55
 DiffGeomBeforeTagging.C:56
 DiffGeomBeforeTagging.C:57
 DiffGeomBeforeTagging.C:58
 DiffGeomBeforeTagging.C:59
 DiffGeomBeforeTagging.C:60
 DiffGeomBeforeTagging.C:61
 DiffGeomBeforeTagging.C:62
 DiffGeomBeforeTagging.C:63
 DiffGeomBeforeTagging.C:64
 DiffGeomBeforeTagging.C:65
 DiffGeomBeforeTagging.C:66
 DiffGeomBeforeTagging.C:67
 DiffGeomBeforeTagging.C:68
 DiffGeomBeforeTagging.C:69
 DiffGeomBeforeTagging.C:70
 DiffGeomBeforeTagging.C:71
 DiffGeomBeforeTagging.C:72
 DiffGeomBeforeTagging.C:73
 DiffGeomBeforeTagging.C:74
 DiffGeomBeforeTagging.C:75
 DiffGeomBeforeTagging.C:76
 DiffGeomBeforeTagging.C:77
 DiffGeomBeforeTagging.C:78
 DiffGeomBeforeTagging.C:79
 DiffGeomBeforeTagging.C:80
 DiffGeomBeforeTagging.C:81
 DiffGeomBeforeTagging.C:82
 DiffGeomBeforeTagging.C:83
 DiffGeomBeforeTagging.C:84
 DiffGeomBeforeTagging.C:85
 DiffGeomBeforeTagging.C:86
 DiffGeomBeforeTagging.C:87
 DiffGeomBeforeTagging.C:88
 DiffGeomBeforeTagging.C:89
 DiffGeomBeforeTagging.C:90
 DiffGeomBeforeTagging.C:91
 DiffGeomBeforeTagging.C:92
 DiffGeomBeforeTagging.C:93
 DiffGeomBeforeTagging.C:94
 DiffGeomBeforeTagging.C:95
 DiffGeomBeforeTagging.C:96
 DiffGeomBeforeTagging.C:97
 DiffGeomBeforeTagging.C:98
 DiffGeomBeforeTagging.C:99
 DiffGeomBeforeTagging.C:100
 DiffGeomBeforeTagging.C:101
 DiffGeomBeforeTagging.C:102
 DiffGeomBeforeTagging.C:103
 DiffGeomBeforeTagging.C:104
 DiffGeomBeforeTagging.C:105
 DiffGeomBeforeTagging.C:106
 DiffGeomBeforeTagging.C:107
 DiffGeomBeforeTagging.C:108
 DiffGeomBeforeTagging.C:109
 DiffGeomBeforeTagging.C:110
 DiffGeomBeforeTagging.C:111
 DiffGeomBeforeTagging.C:112
 DiffGeomBeforeTagging.C:113
 DiffGeomBeforeTagging.C:114
 DiffGeomBeforeTagging.C:115
 DiffGeomBeforeTagging.C:116
 DiffGeomBeforeTagging.C:117
 DiffGeomBeforeTagging.C:118
 DiffGeomBeforeTagging.C:119
 DiffGeomBeforeTagging.C:120
 DiffGeomBeforeTagging.C:121
 DiffGeomBeforeTagging.C:122
 DiffGeomBeforeTagging.C:123
 DiffGeomBeforeTagging.C:124
 DiffGeomBeforeTagging.C:125
 DiffGeomBeforeTagging.C:126
 DiffGeomBeforeTagging.C:127
 DiffGeomBeforeTagging.C:128
 DiffGeomBeforeTagging.C:129
 DiffGeomBeforeTagging.C:130
 DiffGeomBeforeTagging.C:131
 DiffGeomBeforeTagging.C:132
 DiffGeomBeforeTagging.C:133
 DiffGeomBeforeTagging.C:134
 DiffGeomBeforeTagging.C:135
 DiffGeomBeforeTagging.C:136
 DiffGeomBeforeTagging.C:137
 DiffGeomBeforeTagging.C:138
 DiffGeomBeforeTagging.C:139
 DiffGeomBeforeTagging.C:140