ROOT logo
/** 
 * Get a collection from a file directory
 * 
 * @param dir   Parent directory 
 * @param name  Name of collection
 * 
 * @return collection or null
 */
TCollection* GetCollection(TDirectory* dir, const TString& name)
{
  if (!dir) { 
    Error("GetCollection", "No parent directory for %s", name.Data());
    return 0;
  }
  TCollection* ret = 0;
  dir->GetObject(name, ret);
  if (!ret) { 
    Error("GetCollection", "Couldn't find %s in %s", 
	  name.Data(), dir->GetName());
    return 0;
  }
  return ret;
}
/** 
 * Get an object from a collection.  Optionally, we check that the
 * type of the possibly found object matches the request.
 * 
 * @param parent Parent collection
 * @param name   Name of object 
 * @param cls If specified, check that the found object (if any) is of
 * this class.
 * 
 * @return Found object (possibly type-checked) or null
 */
TObject* GetObject(const TCollection* parent, const TString& name, 
		   const TClass* cls=0)
{
  if (!parent) { 
    Error("GetObject", "No parent collection for %s", name.Data());
    return 0;
  }
  TObject* ret = parent->FindObject(name);
  if (!ret) {
    Error("GetObject", "Couldn't find %s in %s", 
	  name.Data(), parent->GetName());
    return 0;
  }
  if (cls && !ret->IsA()->InheritsFrom(cls)) { 
    Error("GetObject", "%s in %s is a %s, not a %s", name.Data(),
	  parent->GetName(), ret->ClassName(), cls->GetName());
    return 0;
  }
  return ret;
}
/** 
 * Get a collection contained in another collection
 * 
 * @param parent Parent collection
 * @param name   Name of collection to find 
 * 
 * @return Found collection or null
 */
TCollection* GetCollection(const TCollection* parent, const TString& name)
{
  TObject* o = GetObject(parent, name, TCollection::Class());
  if (!o) return 0;
  return static_cast<TCollection*>(o);
}
/** 
 * Re-run the energy loss fitter on a merged output file 
 * 
 * @param input  File name of merged output file
 * @param output If specified, the file the new results are written
 * to.  If this is not specified, it defaults to the name of the input
 * file with "_rerun" attached to the base name
 *
 * @param forceSet  Forcibly set things 
 * @param input     Input file 
 * @param output    Output file 
 */
void RerunTrackELoss(Bool_t forceSet=false, 
		     const TString& input="forward_mctracks.root", 
		     Bool_t shift=true,
		     const TString& output="")
{
  const char* fwd = "$ALICE_ROOT/PWGLF/FORWARD/analysis2";
  gROOT->Macro(Form("%s/scripts/LoadLibs.C", fwd));

  TFile*  inFile  = 0;
  TFile*  outFile = 0;
  TString outName(output);
  if (outName.IsNull()) {
    outName = input;
    outName.ReplaceAll(".root", "_rerun.root");
  }
  Bool_t  allOk = false;
  try {
    // --- Open input file ---------------------------------------------
    inFile = TFile::Open(input, "READ");
    if (!inFile)
      throw TString::Format("Failed to open %s", input.Data());

    // --- InFiled input collections --------------------------------------
    TCollection* inFwdSum = GetCollection(inFile, "ForwardTracksSums");
    if (!inFwdSum) throw new TString("Cannot proceed without sums");

    TCollection* inFwdRes = GetCollection(inFile, "ForwardTracksResults");
    if (!inFwdRes) {
      inFwdRes = 
	static_cast<TCollection*>(inFwdSum->Clone("ForwardTracksResults"));
      // throw new TString("Cannot proceed with merged list");
    }

    TCollection* inEFSum = GetCollection(inFwdRes, "fmdEnergyFitter");
    if (!inEFSum) throw new TString("Cannot proceed without accumulated data");
    
    TCollection* inEFRes = GetCollection(inFwdRes, "fmdEnergyFitter");
    if (!inEFRes) throw new TString("Cannot proceed without previous results");

    // --- Open output file --------------------------------------------
    outFile = TFile::Open(outName, "RECREATE");
    if (!outFile)
      throw TString::Format("Failed to open %s", outName.Data());

    // --- Write copy of sum collection to output --------------------
    TCollection* outFwdSum = static_cast<TCollection*>(inFwdSum->Clone());
    outFile->cd();
    outFwdSum->Write(inFwdSum->GetName(), TObject::kSingleKey);
    
    // --- Make our fitter object ------------------------------------
    AliFMDMCTrackInspector* fitter = new AliFMDMCTrackInspector("energy");
    fitter->SetDoFits(true);
    fitter->SetDoMakeObject(false);
    fitter->SetEnableDeltaShift(shift);
    fitter->Init();
    if (forceSet || !fitter->ReadParameters(inEFSum)) {
      Printf("Forced settings");

      const TAxis* etaAxis = static_cast<TAxis*>(GetObject(inEFSum,"etaAxis"));
      if (!etaAxis) throw new TString("Cannot proceed without eta axis");
      fitter->SetEtaAxis(*etaAxis);
      
      // Set maximum energy loss to consider 
      fitter->SetMaxE(15); 
      // Set number of energy loss bins 
      fitter->SetNEbins(500);
      // Set whether to use increasing bin sizes 
      // fitter->SetUseIncreasingBins(true);
      // Set whether to do fit the energy distributions 
      fitter->SetDoFits(kTRUE);
      // Set the low cut used for energy
      fitter->SetLowCut(0.4);
      // Set the number of bins to subtract from maximum of distributions
      // to get the lower bound of the fit range
      fitter->SetFitRangeBinWidth(4);
      // Set the maximum number of landaus to try to fit (max 5)
      fitter->SetNParticles(5);
      // Set the minimum number of entries in the distribution before
      // trying to fit to the data - 10k seems the least we can do
      fitter->SetMinEntries(10000);
      // fitter->SetMaxChi2PerNDF(10);
      // Enable debug 
    }
    fitter->SetDoMakeObject(false);
    fitter->SetDebug(3);
    fitter->SetStoreResiduals(AliFMDEnergyFitter::kResidualSquareDifference);
    fitter->SetRegularizationCut(1e8); // Lower by factor 3
    // Set the number of bins to subtract from maximum of distributions
    // to get the lower bound of the fit range
    // fitter->SetFitRangeBinWidth(2);
    // Skip all of FMD2 and 3 
    // fitter->SetSkips(AliFMDEnergyFitter::kFMD2|AliFMDEnergyFitter::kFMD3);

    // --- Now do the fits -------------------------------------------
    fitter->Print();
    outFwdSum->ls("R");
    fitter->Fit(static_cast<TList*>(outFwdSum));
    
    // --- Copy full result folder -----------------------------------
    TCollection* outFwdRes = static_cast<TCollection*>(inFwdRes->Clone());
    // Remove old fits 
    TCollection* outEFRes = GetCollection(outFwdRes, "fmdEnergyFitter");
    outFwdRes->Remove(outEFRes);
    // Make our new fit results folder, and add it to results folder
    TCollection* tmp = GetCollection(outFwdSum, "fmdEnergyFitter");
    outEFRes = static_cast<TCollection*>(tmp->Clone());
    outEFRes->Add(new TNamed("refitted", "Refit of the data"));
    outFwdRes->Add(outEFRes);

    // --- Write out new results folder ------------------------------
    outFile->cd();
    outFwdRes->Write(inFwdRes->GetName(), TObject::kSingleKey);
    Printf("Wrote results to \"%s\" (%s)", outName.Data(), outFile->GetName());
    allOk = true;
  }
  catch (const TString* e) {
    Error("RerunELossFits", e->Data());
  }
  catch (const TString& e) {
    Error("RerunELossFits", e.Data());
  }
  if (inFile)  inFile->Close();
  if (outFile) {
    Printf("Wrote new output to \"%s\"", outName.Data());
    outFile->Close();
  }
    
  if (allOk) { 
    gROOT->LoadMacro(Form("%s/scripts/SummaryMCTrackDrawer.C+g",fwd));
    SummaryMCTrackDrawer smd;
    smd.Run(outName.Data(),0x10F);
  }
}


 RerunTrackELoss.C:1
 RerunTrackELoss.C:2
 RerunTrackELoss.C:3
 RerunTrackELoss.C:4
 RerunTrackELoss.C:5
 RerunTrackELoss.C:6
 RerunTrackELoss.C:7
 RerunTrackELoss.C:8
 RerunTrackELoss.C:9
 RerunTrackELoss.C:10
 RerunTrackELoss.C:11
 RerunTrackELoss.C:12
 RerunTrackELoss.C:13
 RerunTrackELoss.C:14
 RerunTrackELoss.C:15
 RerunTrackELoss.C:16
 RerunTrackELoss.C:17
 RerunTrackELoss.C:18
 RerunTrackELoss.C:19
 RerunTrackELoss.C:20
 RerunTrackELoss.C:21
 RerunTrackELoss.C:22
 RerunTrackELoss.C:23
 RerunTrackELoss.C:24
 RerunTrackELoss.C:25
 RerunTrackELoss.C:26
 RerunTrackELoss.C:27
 RerunTrackELoss.C:28
 RerunTrackELoss.C:29
 RerunTrackELoss.C:30
 RerunTrackELoss.C:31
 RerunTrackELoss.C:32
 RerunTrackELoss.C:33
 RerunTrackELoss.C:34
 RerunTrackELoss.C:35
 RerunTrackELoss.C:36
 RerunTrackELoss.C:37
 RerunTrackELoss.C:38
 RerunTrackELoss.C:39
 RerunTrackELoss.C:40
 RerunTrackELoss.C:41
 RerunTrackELoss.C:42
 RerunTrackELoss.C:43
 RerunTrackELoss.C:44
 RerunTrackELoss.C:45
 RerunTrackELoss.C:46
 RerunTrackELoss.C:47
 RerunTrackELoss.C:48
 RerunTrackELoss.C:49
 RerunTrackELoss.C:50
 RerunTrackELoss.C:51
 RerunTrackELoss.C:52
 RerunTrackELoss.C:53
 RerunTrackELoss.C:54
 RerunTrackELoss.C:55
 RerunTrackELoss.C:56
 RerunTrackELoss.C:57
 RerunTrackELoss.C:58
 RerunTrackELoss.C:59
 RerunTrackELoss.C:60
 RerunTrackELoss.C:61
 RerunTrackELoss.C:62
 RerunTrackELoss.C:63
 RerunTrackELoss.C:64
 RerunTrackELoss.C:65
 RerunTrackELoss.C:66
 RerunTrackELoss.C:67
 RerunTrackELoss.C:68
 RerunTrackELoss.C:69
 RerunTrackELoss.C:70
 RerunTrackELoss.C:71
 RerunTrackELoss.C:72
 RerunTrackELoss.C:73
 RerunTrackELoss.C:74
 RerunTrackELoss.C:75
 RerunTrackELoss.C:76
 RerunTrackELoss.C:77
 RerunTrackELoss.C:78
 RerunTrackELoss.C:79
 RerunTrackELoss.C:80
 RerunTrackELoss.C:81
 RerunTrackELoss.C:82
 RerunTrackELoss.C:83
 RerunTrackELoss.C:84
 RerunTrackELoss.C:85
 RerunTrackELoss.C:86
 RerunTrackELoss.C:87
 RerunTrackELoss.C:88
 RerunTrackELoss.C:89
 RerunTrackELoss.C:90
 RerunTrackELoss.C:91
 RerunTrackELoss.C:92
 RerunTrackELoss.C:93
 RerunTrackELoss.C:94
 RerunTrackELoss.C:95
 RerunTrackELoss.C:96
 RerunTrackELoss.C:97
 RerunTrackELoss.C:98
 RerunTrackELoss.C:99
 RerunTrackELoss.C:100
 RerunTrackELoss.C:101
 RerunTrackELoss.C:102
 RerunTrackELoss.C:103
 RerunTrackELoss.C:104
 RerunTrackELoss.C:105
 RerunTrackELoss.C:106
 RerunTrackELoss.C:107
 RerunTrackELoss.C:108
 RerunTrackELoss.C:109
 RerunTrackELoss.C:110
 RerunTrackELoss.C:111
 RerunTrackELoss.C:112
 RerunTrackELoss.C:113
 RerunTrackELoss.C:114
 RerunTrackELoss.C:115
 RerunTrackELoss.C:116
 RerunTrackELoss.C:117
 RerunTrackELoss.C:118
 RerunTrackELoss.C:119
 RerunTrackELoss.C:120
 RerunTrackELoss.C:121
 RerunTrackELoss.C:122
 RerunTrackELoss.C:123
 RerunTrackELoss.C:124
 RerunTrackELoss.C:125
 RerunTrackELoss.C:126
 RerunTrackELoss.C:127
 RerunTrackELoss.C:128
 RerunTrackELoss.C:129
 RerunTrackELoss.C:130
 RerunTrackELoss.C:131
 RerunTrackELoss.C:132
 RerunTrackELoss.C:133
 RerunTrackELoss.C:134
 RerunTrackELoss.C:135
 RerunTrackELoss.C:136
 RerunTrackELoss.C:137
 RerunTrackELoss.C:138
 RerunTrackELoss.C:139
 RerunTrackELoss.C:140
 RerunTrackELoss.C:141
 RerunTrackELoss.C:142
 RerunTrackELoss.C:143
 RerunTrackELoss.C:144
 RerunTrackELoss.C:145
 RerunTrackELoss.C:146
 RerunTrackELoss.C:147
 RerunTrackELoss.C:148
 RerunTrackELoss.C:149
 RerunTrackELoss.C:150
 RerunTrackELoss.C:151
 RerunTrackELoss.C:152
 RerunTrackELoss.C:153
 RerunTrackELoss.C:154
 RerunTrackELoss.C:155
 RerunTrackELoss.C:156
 RerunTrackELoss.C:157
 RerunTrackELoss.C:158
 RerunTrackELoss.C:159
 RerunTrackELoss.C:160
 RerunTrackELoss.C:161
 RerunTrackELoss.C:162
 RerunTrackELoss.C:163
 RerunTrackELoss.C:164
 RerunTrackELoss.C:165
 RerunTrackELoss.C:166
 RerunTrackELoss.C:167
 RerunTrackELoss.C:168
 RerunTrackELoss.C:169
 RerunTrackELoss.C:170
 RerunTrackELoss.C:171
 RerunTrackELoss.C:172
 RerunTrackELoss.C:173
 RerunTrackELoss.C:174
 RerunTrackELoss.C:175
 RerunTrackELoss.C:176
 RerunTrackELoss.C:177
 RerunTrackELoss.C:178
 RerunTrackELoss.C:179
 RerunTrackELoss.C:180
 RerunTrackELoss.C:181
 RerunTrackELoss.C:182
 RerunTrackELoss.C:183
 RerunTrackELoss.C:184
 RerunTrackELoss.C:185
 RerunTrackELoss.C:186
 RerunTrackELoss.C:187
 RerunTrackELoss.C:188
 RerunTrackELoss.C:189
 RerunTrackELoss.C:190
 RerunTrackELoss.C:191
 RerunTrackELoss.C:192
 RerunTrackELoss.C:193
 RerunTrackELoss.C:194
 RerunTrackELoss.C:195
 RerunTrackELoss.C:196
 RerunTrackELoss.C:197
 RerunTrackELoss.C:198
 RerunTrackELoss.C:199
 RerunTrackELoss.C:200
 RerunTrackELoss.C:201
 RerunTrackELoss.C:202
 RerunTrackELoss.C:203
 RerunTrackELoss.C:204
 RerunTrackELoss.C:205
 RerunTrackELoss.C:206
 RerunTrackELoss.C:207
 RerunTrackELoss.C:208
 RerunTrackELoss.C:209
 RerunTrackELoss.C:210
 RerunTrackELoss.C:211
 RerunTrackELoss.C:212
 RerunTrackELoss.C:213
 RerunTrackELoss.C:214
 RerunTrackELoss.C:215
 RerunTrackELoss.C:216