ROOT logo
/*
This macro loops over all the cluster (output of compClusHits.C) and creates a database containing the topologies of the cluster and infromation about:
pattern in TBits format, coordinate of the centre of the pixel contining the COG wrt down-left corner of the osculating rectangle (fraction of the pixel pithc),
distance between COG and centre of the pixel (fraction), number of fired pixels, number of colums, number of rows.
*/

#if !defined(__CInt_t__) || defined(__MAKECInt_t__)
#include "AliESDEvent.h"
#include "TObjArray.h"
#include "TFile.h"
#include "TTree.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TCanvas.h"
#include "TLegend.h"
#include "TBits.h"
#include "TArrayI.h"
#include "TArrayF.h"
#include "../ITS/UPGRADE/AliITSUClusterPix.h"
#include "../ITS/UPGRADE/AliITSURecoLayer.h"
#include "../ITS/UPGRADE/AliITSURecoDet.h"
#include "../ITS/UPGRADE/AliITSUHit.h"
#include "../ITS/UPGRADE/AliITSUGeomTGeo.h"
#include "AliITSsegmentation.h"
#include "AliGeomManager.h"

#endif

TTree* treeInp = 0;
TTree* cluTree = 0;
AliRunLoader* runLoader = 0;
AliESDEvent* esd=0;

AliITSUGeomTGeo* gm=0;
Int_t nLayers = 0;
AliITSURecoDet *its = 0;
TObjArray patterns;
TArrayF pattCount;
Int_t nPatterns=0,nClusters=0;
TString outDBFileName = "clusterTopology.root";

void ProcessEvent(Int_t iev);
void ProcChunk(const char* path);
void BuildClTopDB(const char* inpData="AliESDs.root", const char* outDBFile="clusterTopology.root");
void AccountTopology(TBits& patt);
void CreateDB();

void BuildClTopDB(const char* inpData, const char* outDBFile)
{
  //
  // parse input list of single root file and process it
  outDBFileName = outDBFile;
  if (outDBFileName.IsNull()) outDBFileName = "clusterTopology.root";
  //
  AliGeomManager::LoadGeometry("geometry.root");
  gm = new AliITSUGeomTGeo(kTRUE);
  AliITSUClusterPix::SetGeom(gm);
  nLayers = gm->GetNLayers();
  its = new AliITSURecoDet(gm, "ITSInt_terface");
  its->CreateClusterArrays();
  esd = new AliESDEvent();
  //
  //
  TString inpDtStr = inpData;
  if (inpDtStr.EndsWith(".root") || inpDtStr.EndsWith(".zip#")) {
    ProcChunk(inpDtStr.Data());
  }
  else {
    ifstream inpf(inpData);
    if (!inpf.good()) {
      printf("Failed on input filename %s\n",inpData);
      return;
    }
    //
    inpDtStr.ReadLine(inpf);
    while ( !inpDtStr.IsNull() ) {
      inpDtStr = inpDtStr.Strip(TString::kBoth,' ');
      if (inpDtStr.BeginsWith("//") || inpDtStr.BeginsWith("#")) {inpDtStr.ReadLine(inpf); continue;}
      inpDtStr = inpDtStr.Strip(TString::kBoth,',');
      inpDtStr = inpDtStr.Strip(TString::kBoth,'"');
      ProcChunk(inpDtStr.Data());
      inpDtStr.ReadLine(inpf);
    }
  }
  //
  CreateDB();
  //
}

void CreateDB()
{
  // sort patterns according to frequencies and store them
  printf("Storing %d patterns in %s\n",nPatterns, outDBFileName.Data());
  if (nPatterns<1) {
    printf("No patterns found\n");
    return;
  }
  TArrayI sortIndex;
  sortIndex.Set(nPatterns);
  TMath::Sort(nPatterns,pattCount.GetArray(),sortIndex.GetArray());
  //
  //create a file.txt containing topologies and corresponding frequecies
  ofstream top("topologies.txt");

  TObjArray arrStore(nPatterns);
  TVectorF arrFreq(nPatterns);
  TVectorF arrzCOGPix(nPatterns); //It's the cordinate of the pixel containing along the rows direction
  TVectorF arrxCOGPix(nPatterns); //It's the COG cordinate along the columns direction
  TVectorF arrzCOGshift(nPatterns); //It's the distance between COG and the centre of the pixel containing COG
  TVectorF arrxCOGshift(nPatterns);
  TVectorF arrNpix(nPatterns);
  TVectorF arrNcol(nPatterns);
  TVectorF arrNrow(nPatterns);

  TCanvas* cnv = new TCanvas("cnv","Freq",900,600);
  TH1F* hfreq = new TH1F("hfreq","Pattern frequency",300/2,-0.5, 300/2-0.5);
  hfreq->SetStats(0);
  hfreq->GetXaxis()->SetTitle("pattern ID");
  hfreq->SetFillColor(kRed);
  hfreq->SetFillStyle(3005);
  TLegend* leg = new TLegend(70, 300000, 140,450000 ,"","");
  leg->AddEntry((TObject*)0, Form("Number of patterns: %d",nPatterns), "");
  leg->AddEntry((TObject*)0, "Number of events: 50", "");
  leg->SetFillColor(0);
  leg->SetBorderSize(0);
  
  for (Int_t i=0;i<nPatterns;i++) {
    Int_t ind = sortIndex[i];
    Float_t fr = arrFreq[i] = Float_t(pattCount[ind])/nClusters;
    arrStore.AddAt(patterns[ind],i);
    UInt_t idd = patterns[ind]->GetUniqueID();

    hfreq->Fill(i,pattCount[ind]);

    Int_t firedPixels=0;
    Int_t tempxCOG=0;
    Int_t tempzCOG=0;

    Int_t rc = idd>>16;//It's the rows span
    Int_t cl = idd&0xffff;//It's the columns span
    top << Form("\nPatt %4d R:%d C: %d Freq:%f \n\n",i,rc,cl,fr);
    for (Int_t ir=rc;ir--;) {
      top << "|"; 
      for (Int_t ic=0; ic<cl; ic++) {
        top << Form("%c",((TBits*)patterns[ind])->TestBitNumber(ir*cl+ic) ? '+':' ');
        if(((TBits*)patterns[ind])->TestBitNumber(ir*cl+ic)){
          firedPixels++;
          tempxCOG+=ir;
          tempzCOG+=ic;
        }
      }
      top << ("|\n");
    }
    Float_t xsh=Float_t((tempxCOG%firedPixels))/firedPixels; //distance between COG end centre of the pixel containing COG
    Float_t zsh=Float_t((tempzCOG%firedPixels))/firedPixels;
    tempxCOG/=firedPixels;
    tempzCOG/=firedPixels;
    if(xsh>0.5){
      tempxCOG+=1;
      xsh-=1;
    }
    if(zsh>0.5){
      tempzCOG+=1;
      zsh-=1;
    }
    Float_t xc=(Float_t) tempxCOG+0.5;
    Float_t zc=(Float_t) tempzCOG+0.5;
    arrxCOGPix[i]=xc;
    arrxCOGshift[i]=xsh;
    arrzCOGPix[i]=zc;
    arrzCOGshift[i]=zsh;
    arrNpix[i]=firedPixels;
    arrNrow[i]=rc;
    arrNcol[i]=cl;
    
    top << "\nxCentre: " <<  xc << " + " << xsh
    <<" zCentre: " << zc << " + " << zsh <<"\n\n...............................................\n";
  }

  cnv->cd();
  hfreq->Draw();
  leg->Draw();
  cnv->Print("Pattern_freq.jpg");

  top.close();

  printf("\nWe have %d clusters corresponding to %d patterns!!!\nEnjoy!!\n\n", nClusters, nPatterns);

  /*
  //Controlling if frequencies have been stored correctly
  ofstream a("frequency.txt");
  a << setw(15) << "i" << setw(20) << "Frequency" << endl;
  for(Int_t i=0; i<nPatterns; i++) a << setw(15) << i << setw(20) << arrFreq[i] << endl;
  a.close();
  */
  //
  TFile* flDB = TFile::Open(outDBFileName.Data(), "recreate");
  flDB->WriteObject(&arrStore,"TopDB","kSingleKey");
  flDB->WriteObject(&arrFreq, "TopFreq","kSingleKey");
  flDB->WriteObject(&arrxCOGPix,"xCOG","kSingleKey");
  flDB->WriteObject(&arrxCOGshift,"xShift","kSingleKey");
  flDB->WriteObject(&arrzCOGPix,"zCOG","kSingleKey");
  flDB->WriteObject(&arrzCOGshift,"zShift","kSingleKey");
  flDB->WriteObject(&arrNpix,"NPix","kSingleKey");
  flDB->WriteObject(&arrNrow,"NRow","kSingleKey");
  flDB->WriteObject(&arrNcol,"NCol","kSingleKey");
  //
  flDB->Close();
  delete flDB;
}

void ProcChunk(const char* path)
{
  //
  TString dir=path;
  //
  printf("Processing %s\n",dir.Data());
  //
  if (dir.EndsWith("AliESDs.root")) {
    dir.ReplaceAll("AliESDs.root","");
  }
  //
  //
  runLoader = AliRunLoader::Open(Form("%sgalice.root",dir.Data()));
  if (!runLoader) {
    printf("galice not found\n");
    return;
  }
  runLoader->LoadgAlice();
  gAlice = runLoader->GetAliRun();
  //  runLoader->LoadHeader();
  //  runLoader->LoadKinematics();
  runLoader->LoadRecPoints("ITS");
  // ESD
  TFile* esdFile = TFile::Open(Form("%sAliESDs.root",dir.Data()));
  if (!esdFile || !esdFile->IsOpen()) {
    printf("Error in opening ESD file\n");
    //    runLoader->UnloadKinematics();
    //    runLoader->UnloadHeader();
    runLoader->UnloadgAlice();
    delete runLoader;
    return;
  }

  treeInp = (TTree*) esdFile->Get("esdTree");
  if (!treeInp) {
    printf("Error: no ESD tree found\n");
    //    runLoader->UnloadKinematics();
    //    runLoader->UnloadHeader();
    runLoader->UnloadgAlice();
    delete runLoader;
    return;
  }
  esd->ReadFromTree(treeInp);
  //
  for (Int_t iEv=0;iEv<runLoader->GetNumberOfEvents(); iEv++) {
    ProcessEvent(iEv);
  }
  runLoader->UnloadRecPoints("all");
  //  runLoader->UnloadKinematics();
  //  runLoader->UnloadHeader();
  runLoader->UnloadgAlice();
  delete runLoader; 
  runLoader = 0;
  esdFile->Close();
  delete esdFile;
}


void ProcessEvent(Int_t iEv) 
{
  // process single event clusters
  runLoader->GetEvent(iEv);
  treeInp->GetEvent(iEv);
  cluTree = runLoader->GetTreeR("ITS",kFALSE);
  if (!cluTree) {
    printf("Did not get cluster tree for event %d\n",iEv);
    return;
  }
  //
  for (Int_t ilr=0;ilr<nLayers;ilr++) {
    TBranch* br = cluTree->GetBranch(Form("ITSRecPoints%d",ilr));
    if (!br) {printf("Did not find cluster branch for lr %d\n",ilr); exit(1);}
    br->SetAddress(its->GetLayerActive(ilr)->GetClustersAddress());
  }
  cluTree->GetEntry(0); 
  its->ProcessClusters();
  //
  TBits currTop;
  //
  for (Int_t ilr=0;ilr<nLayers;ilr++) {
    AliITSURecoLayer* lr = its->GetLayerActive(ilr);
    TClonesArray* clr = lr->GetClusters();
    Int_t nClu = clr->GetEntries();
    printf("Ev%d Lr:%d Ncl:%d\n",iEv,ilr,nClu);
    //    printf("Layer %d : %d clusters\n",ilr,nClu);
    //
    for (Int_t icl=0;icl<nClu;icl++) {
      AliITSUClusterPix *cl = (AliITSUClusterPix*)clr->At(icl);
      currTop.Clear();
      UShort_t rs = (UShort_t)cl->GetPatternRowSpan();
      UShort_t cs = (UShort_t)cl->GetPatternColSpan();
      for (Int_t ir=0;ir<rs;ir++)
	     for (Int_t ic=0;ic<cs;ic++) 
	       if (cl->TestPixel(ir,ic)) currTop.SetBitNumber(ir*cs+ic);
      //
      currTop.SetUniqueID( (rs<<16) + (cs));
      //
      AccountTopology(currTop);
    }
  }
  //
}

//___________________________________________
void AccountTopology(TBits& patt)
{
  // account topology in the database
  Bool_t newPatt = kTRUE;
  nClusters++;
  for (Int_t ip=0;ip<nPatterns;ip++) {
    TBits* pattOld = (TBits*)patterns.At(ip);
    if (*pattOld == patt && pattOld->GetUniqueID()==patt.GetUniqueID()) {
      // require that the matrix size and the bit patterns are equal
      newPatt = kFALSE;
      pattCount[ip]++;
      break;
    }
  }
  //
  if (newPatt) {
    TBits* pt = new TBits(patt);
    patterns.AddLast(pt);
    if (pattCount.GetSize()<nPatterns+100) pattCount.Set(nPatterns+100);
    pattCount[nPatterns++] = 1;
  }
  //
 BuildClTopDB.C:1
 BuildClTopDB.C:2
 BuildClTopDB.C:3
 BuildClTopDB.C:4
 BuildClTopDB.C:5
 BuildClTopDB.C:6
 BuildClTopDB.C:7
 BuildClTopDB.C:8
 BuildClTopDB.C:9
 BuildClTopDB.C:10
 BuildClTopDB.C:11
 BuildClTopDB.C:12
 BuildClTopDB.C:13
 BuildClTopDB.C:14
 BuildClTopDB.C:15
 BuildClTopDB.C:16
 BuildClTopDB.C:17
 BuildClTopDB.C:18
 BuildClTopDB.C:19
 BuildClTopDB.C:20
 BuildClTopDB.C:21
 BuildClTopDB.C:22
 BuildClTopDB.C:23
 BuildClTopDB.C:24
 BuildClTopDB.C:25
 BuildClTopDB.C:26
 BuildClTopDB.C:27
 BuildClTopDB.C:28
 BuildClTopDB.C:29
 BuildClTopDB.C:30
 BuildClTopDB.C:31
 BuildClTopDB.C:32
 BuildClTopDB.C:33
 BuildClTopDB.C:34
 BuildClTopDB.C:35
 BuildClTopDB.C:36
 BuildClTopDB.C:37
 BuildClTopDB.C:38
 BuildClTopDB.C:39
 BuildClTopDB.C:40
 BuildClTopDB.C:41
 BuildClTopDB.C:42
 BuildClTopDB.C:43
 BuildClTopDB.C:44
 BuildClTopDB.C:45
 BuildClTopDB.C:46
 BuildClTopDB.C:47
 BuildClTopDB.C:48
 BuildClTopDB.C:49
 BuildClTopDB.C:50
 BuildClTopDB.C:51
 BuildClTopDB.C:52
 BuildClTopDB.C:53
 BuildClTopDB.C:54
 BuildClTopDB.C:55
 BuildClTopDB.C:56
 BuildClTopDB.C:57
 BuildClTopDB.C:58
 BuildClTopDB.C:59
 BuildClTopDB.C:60
 BuildClTopDB.C:61
 BuildClTopDB.C:62
 BuildClTopDB.C:63
 BuildClTopDB.C:64
 BuildClTopDB.C:65
 BuildClTopDB.C:66
 BuildClTopDB.C:67
 BuildClTopDB.C:68
 BuildClTopDB.C:69
 BuildClTopDB.C:70
 BuildClTopDB.C:71
 BuildClTopDB.C:72
 BuildClTopDB.C:73
 BuildClTopDB.C:74
 BuildClTopDB.C:75
 BuildClTopDB.C:76
 BuildClTopDB.C:77
 BuildClTopDB.C:78
 BuildClTopDB.C:79
 BuildClTopDB.C:80
 BuildClTopDB.C:81
 BuildClTopDB.C:82
 BuildClTopDB.C:83
 BuildClTopDB.C:84
 BuildClTopDB.C:85
 BuildClTopDB.C:86
 BuildClTopDB.C:87
 BuildClTopDB.C:88
 BuildClTopDB.C:89
 BuildClTopDB.C:90
 BuildClTopDB.C:91
 BuildClTopDB.C:92
 BuildClTopDB.C:93
 BuildClTopDB.C:94
 BuildClTopDB.C:95
 BuildClTopDB.C:96
 BuildClTopDB.C:97
 BuildClTopDB.C:98
 BuildClTopDB.C:99
 BuildClTopDB.C:100
 BuildClTopDB.C:101
 BuildClTopDB.C:102
 BuildClTopDB.C:103
 BuildClTopDB.C:104
 BuildClTopDB.C:105
 BuildClTopDB.C:106
 BuildClTopDB.C:107
 BuildClTopDB.C:108
 BuildClTopDB.C:109
 BuildClTopDB.C:110
 BuildClTopDB.C:111
 BuildClTopDB.C:112
 BuildClTopDB.C:113
 BuildClTopDB.C:114
 BuildClTopDB.C:115
 BuildClTopDB.C:116
 BuildClTopDB.C:117
 BuildClTopDB.C:118
 BuildClTopDB.C:119
 BuildClTopDB.C:120
 BuildClTopDB.C:121
 BuildClTopDB.C:122
 BuildClTopDB.C:123
 BuildClTopDB.C:124
 BuildClTopDB.C:125
 BuildClTopDB.C:126
 BuildClTopDB.C:127
 BuildClTopDB.C:128
 BuildClTopDB.C:129
 BuildClTopDB.C:130
 BuildClTopDB.C:131
 BuildClTopDB.C:132
 BuildClTopDB.C:133
 BuildClTopDB.C:134
 BuildClTopDB.C:135
 BuildClTopDB.C:136
 BuildClTopDB.C:137
 BuildClTopDB.C:138
 BuildClTopDB.C:139
 BuildClTopDB.C:140
 BuildClTopDB.C:141
 BuildClTopDB.C:142
 BuildClTopDB.C:143
 BuildClTopDB.C:144
 BuildClTopDB.C:145
 BuildClTopDB.C:146
 BuildClTopDB.C:147
 BuildClTopDB.C:148
 BuildClTopDB.C:149
 BuildClTopDB.C:150
 BuildClTopDB.C:151
 BuildClTopDB.C:152
 BuildClTopDB.C:153
 BuildClTopDB.C:154
 BuildClTopDB.C:155
 BuildClTopDB.C:156
 BuildClTopDB.C:157
 BuildClTopDB.C:158
 BuildClTopDB.C:159
 BuildClTopDB.C:160
 BuildClTopDB.C:161
 BuildClTopDB.C:162
 BuildClTopDB.C:163
 BuildClTopDB.C:164
 BuildClTopDB.C:165
 BuildClTopDB.C:166
 BuildClTopDB.C:167
 BuildClTopDB.C:168
 BuildClTopDB.C:169
 BuildClTopDB.C:170
 BuildClTopDB.C:171
 BuildClTopDB.C:172
 BuildClTopDB.C:173
 BuildClTopDB.C:174
 BuildClTopDB.C:175
 BuildClTopDB.C:176
 BuildClTopDB.C:177
 BuildClTopDB.C:178
 BuildClTopDB.C:179
 BuildClTopDB.C:180
 BuildClTopDB.C:181
 BuildClTopDB.C:182
 BuildClTopDB.C:183
 BuildClTopDB.C:184
 BuildClTopDB.C:185
 BuildClTopDB.C:186
 BuildClTopDB.C:187
 BuildClTopDB.C:188
 BuildClTopDB.C:189
 BuildClTopDB.C:190
 BuildClTopDB.C:191
 BuildClTopDB.C:192
 BuildClTopDB.C:193
 BuildClTopDB.C:194
 BuildClTopDB.C:195
 BuildClTopDB.C:196
 BuildClTopDB.C:197
 BuildClTopDB.C:198
 BuildClTopDB.C:199
 BuildClTopDB.C:200
 BuildClTopDB.C:201
 BuildClTopDB.C:202
 BuildClTopDB.C:203
 BuildClTopDB.C:204
 BuildClTopDB.C:205
 BuildClTopDB.C:206
 BuildClTopDB.C:207
 BuildClTopDB.C:208
 BuildClTopDB.C:209
 BuildClTopDB.C:210
 BuildClTopDB.C:211
 BuildClTopDB.C:212
 BuildClTopDB.C:213
 BuildClTopDB.C:214
 BuildClTopDB.C:215
 BuildClTopDB.C:216
 BuildClTopDB.C:217
 BuildClTopDB.C:218
 BuildClTopDB.C:219
 BuildClTopDB.C:220
 BuildClTopDB.C:221
 BuildClTopDB.C:222
 BuildClTopDB.C:223
 BuildClTopDB.C:224
 BuildClTopDB.C:225
 BuildClTopDB.C:226
 BuildClTopDB.C:227
 BuildClTopDB.C:228
 BuildClTopDB.C:229
 BuildClTopDB.C:230
 BuildClTopDB.C:231
 BuildClTopDB.C:232
 BuildClTopDB.C:233
 BuildClTopDB.C:234
 BuildClTopDB.C:235
 BuildClTopDB.C:236
 BuildClTopDB.C:237
 BuildClTopDB.C:238
 BuildClTopDB.C:239
 BuildClTopDB.C:240
 BuildClTopDB.C:241
 BuildClTopDB.C:242
 BuildClTopDB.C:243
 BuildClTopDB.C:244
 BuildClTopDB.C:245
 BuildClTopDB.C:246
 BuildClTopDB.C:247
 BuildClTopDB.C:248
 BuildClTopDB.C:249
 BuildClTopDB.C:250
 BuildClTopDB.C:251
 BuildClTopDB.C:252
 BuildClTopDB.C:253
 BuildClTopDB.C:254
 BuildClTopDB.C:255
 BuildClTopDB.C:256
 BuildClTopDB.C:257
 BuildClTopDB.C:258
 BuildClTopDB.C:259
 BuildClTopDB.C:260
 BuildClTopDB.C:261
 BuildClTopDB.C:262
 BuildClTopDB.C:263
 BuildClTopDB.C:264
 BuildClTopDB.C:265
 BuildClTopDB.C:266
 BuildClTopDB.C:267
 BuildClTopDB.C:268
 BuildClTopDB.C:269
 BuildClTopDB.C:270
 BuildClTopDB.C:271
 BuildClTopDB.C:272
 BuildClTopDB.C:273
 BuildClTopDB.C:274
 BuildClTopDB.C:275
 BuildClTopDB.C:276
 BuildClTopDB.C:277
 BuildClTopDB.C:278
 BuildClTopDB.C:279
 BuildClTopDB.C:280
 BuildClTopDB.C:281
 BuildClTopDB.C:282
 BuildClTopDB.C:283
 BuildClTopDB.C:284
 BuildClTopDB.C:285
 BuildClTopDB.C:286
 BuildClTopDB.C:287
 BuildClTopDB.C:288
 BuildClTopDB.C:289
 BuildClTopDB.C:290
 BuildClTopDB.C:291
 BuildClTopDB.C:292
 BuildClTopDB.C:293
 BuildClTopDB.C:294
 BuildClTopDB.C:295
 BuildClTopDB.C:296
 BuildClTopDB.C:297
 BuildClTopDB.C:298
 BuildClTopDB.C:299
 BuildClTopDB.C:300
 BuildClTopDB.C:301
 BuildClTopDB.C:302
 BuildClTopDB.C:303
 BuildClTopDB.C:304
 BuildClTopDB.C:305
 BuildClTopDB.C:306
 BuildClTopDB.C:307
 BuildClTopDB.C:308
 BuildClTopDB.C:309
 BuildClTopDB.C:310
 BuildClTopDB.C:311
 BuildClTopDB.C:312
 BuildClTopDB.C:313
 BuildClTopDB.C:314
 BuildClTopDB.C:315
 BuildClTopDB.C:316
 BuildClTopDB.C:317
 BuildClTopDB.C:318
 BuildClTopDB.C:319
 BuildClTopDB.C:320
 BuildClTopDB.C:321
 BuildClTopDB.C:322
 BuildClTopDB.C:323
 BuildClTopDB.C:324
 BuildClTopDB.C:325
 BuildClTopDB.C:326
 BuildClTopDB.C:327
 BuildClTopDB.C:328
 BuildClTopDB.C:329
 BuildClTopDB.C:330
 BuildClTopDB.C:331
 BuildClTopDB.C:332
 BuildClTopDB.C:333
 BuildClTopDB.C:334
 BuildClTopDB.C:335
 BuildClTopDB.C:336
 BuildClTopDB.C:337
 BuildClTopDB.C:338