ROOT logo
/**
 * @file   GRP.C
 * @author Christian Holm Christensen <cholm@nbi.dk>
 * @date   Wed Aug 20 10:00:39 2014
 * 
 * @brief  Class that hold summary of GRP data.
 * 
 * 
 */
// #include <fstream>

/**
 * Class that hold summary of GRP data, and has methods to obtain
 * these, either from a previously dumped file, or directly from OCDB.
 * 
 * This is used by the simulation setup to ensure we have the proper
 * beam settings for an anchor run. 
 */
struct GRPData
{
  /** 
   * A beam 
   */
  struct Beam
  {
    UInt_t z;
    UInt_t a;
    /** 
     * Get the per nucleon beam energy given a per charge beam energy
     * 
     * @param e Per charge beam energy 
     * 
     * @return Per nucleon beam energy 
     */
    Float_t GetEnergy(Float_t e) const 
    {
      return e * sqrt(float(z)/a);
    }
    /** 
     * Check if this is a proton
     * 
     * @return True if z and a are 1 
     */
    Bool_t IsP() const { return z == 1 && a == 1; }
    /** 
     * Check if this is a nucleus 
     * 
     * @return true if not P
     */
    Bool_t IsA() const { return !IsP(); }
    /** 
     * Get the beam type name 
     * 
     * @return P or A
     */
    const char* Name() { return (IsP() ? "P" : IsA() ? "A" : ""); }
    /** 
     * Set the beam type from single beam spec from LHC 
     * 
     * @param b Beam type from LHC 
     */
    void Set(UInt_t b)
    {
      z = b % 1000;
      a = b / 1000;
    }
    /** 
     * Set from either a full LHC spec or from ALICE spec 
     * 
     * @param b Beam
     */
    void Set(const TString& b) 
    {
      b.ToUpper();
      a = 0; 
      z = 0;
      if (b.EqualTo("P") || b.EqualTo("PROTON")) { 
	z = a = 1;
      }
      else if (b.EqualTo("A") || b.BeginsWidth("PB")) {
	z = 82;
	a = 208;
      }
    }
  };
  UInt_t  beamEnergy;
  UInt_t  energy;
  TString period;
  UInt_t  run;
  Beam    beam1;
  Beam    beam2;
  /** 
   * Constructor. 
   * 
   * @param r Run number
   */
  GRPData(UInt_t r) 
    : beamEnergy(0), energy(0), period(""), beam1(), beam2(), run(r)
  {
    Info("GRP", "Will try from file %s", FileName());
    if (!ReadFromFile()) { 
      Warning("GRP", "Failed to read from file, trying from OCDB");
      if (!ReadFromOCDB(run)) 
	Fatal("GRP", "Failed to get GRP values");
    }
    Print();
  }
  /** 
   * Print information 
   * 
   */
  void Print()
  {
    Printf("%s run %d\n"
	   "  Beam energy: %d GeV\n"
	   "  sqrt(s_NN):  %d GeV\n"
	   "  Beam 1:      %s (%d %d)\n"
	   "  Beam 2:      %s (%d %d)",
	   period.Data(), run, beamEnergy, energy, 
	   beam1.Name(), beam1.a, beam1.z,
	   beam2.Name(), beam2.a, beam2.z);
  }
  /** 
   * Check if this run was a p-p run
   * 
   * @return Return true if both beams are p
   */
  Bool_t IsPP() const { return beam1.IsP() && beam2.IsP(); }
  /** 
   * Check if this run was a p-A run
   * 
   * @return Return true beam 1 is p and 2 is A
   */
  Bool_t IsPA() const { return beam1.IsP() && beam2.IsA(); }
  /** 
   * Check if this run was a A-p run
   * 
   * @return Return true beam 1 is A and 2 is p
   */
  Bool_t IsAP() const { return beam1.IsA() && beam2.IsP(); }
  /** 
   * Check if this run was a A-A run
   * 
   * @return Return true if both beams are A
   */
  Bool_t IsAA() const { return beam1.IsA() && beam2.IsA(); }
  /** 
   * Get the year 
   *
   * @return Year 
   */
  UInt_t Year() const 
  {
    TString tmp = period(3,2);
    return tmp.Atoi() + 2000;
  }
  const char* FileName() const { return "grp.dat"; }
  /** 
   * Get unsigned int value from string value of TObjString 
   * 
   * @param o Object
   * 
   * @return value 
   */
  static UInt_t Obj2UInt(const TObject* o) 
  {
    return (static_cast<TObjString*>(o))->String().Atoi();
  }
  /** 
   * Read values from a file 
   * 
   * @return true on success
   */
  Bool_t ReadFromFile() 
  {
    if (gSystem->AccessPathName(FileName())) {
      Info("GRP", "Cannot open file %s", FileName());
      return false;
    }
    
    std::ifstream* pin = new std::ifstream("grp.dat");
    std::ifstream& in  = *pin;
    TString line;
    TString env;
    do {
      line.ReadLine(in);
      if (line.IsNull()) continue;
      if (line[0] == '#') continue;
      env = line;
      break;
    } while (!in.eof());
    if (env.IsNull()) {
      Info("GRP", "No line found");
      return false;
    }
    Info("GRP", "Got the line %s", env.Data());
    TObjArray* tokens = env.Tokenize(":");
    if (tokens->GetEntries() < 8) {
      Warning("GRP", "Failed to get enough field from GRP_SUMMARY=%s",
	      env.Data());
      return false;
    }
    period     = tokens->At(0)->GetName();
    run        = Obj2UInt(tokens->At(1));
    beamEnergy = Obj2UInt(tokens->At(2));
    energy     = Obj2UInt(tokens->At(3));
    beam1.a    = Obj2UInt(tokens->At(4));
    beam1.z    = Obj2UInt(tokens->At(5));
    beam2.a    = Obj2UInt(tokens->At(6));
    beam2.z    = Obj2UInt(tokens->At(7));
    pin->close();
    delete pin;
    return true;
  }
  /** 
   * Read values from OCDB.  Also dumps values to file. 
   * 
   * @param r run number 
   * 
   * @return true on success
   */
  Bool_t ReadFromOCDB(UInt_t r)
  {
     AliCDBManager* cdb = AliCDBManager::Instance();
     cdb->SetDefaultStorageFromRun(r);
     cdb->SetRun(r);
     AliCDBEntry*   ent = cdb->Get("GRP/GRP/Data");
     if (!ent) {
       Warning("GRP", "No GRP data found");
       cdb->SetRun(-1);
       return false;
     }
     Info("GRP", "Got GRP:");
     ent->PrintMetaData();

     AliGRPObject*  obj        = static_cast<AliGRPObject*>(ent->GetObject());
     obj->Print();
     run                       = r;
     period                    = obj->GetLHCPeriod();
     beamEnergy                = TMath::Ceil(obj->GetBeamEnergy());
     TString        beam1T     = obj->GetSingleBeamType(0);
     TString        beam2T     = obj->GetSingleBeamType(1);

     if (!beam1T.IsNull() && !beam2T.IsNull()) {
       beam1.Set(beam1T.Atoi());
       beam2.Set(beam2T.Atoi());
     }
     else {
       TString beamType = obj->GetBeamType();
       if (beamType.IsNull()) {
	 Warning("GRP", "No beam type");
	 cdb->SetRun(-1);
	 return false;
       }
       
       TObjArray* ab  = beamType.Tokenize("-");
       ab->ls();
       beam1T = ab->At(0)->GetName();
       beam2T = ab->At(1)->GetName();
       beam1.Set(beam1T);
       beam2.Set(beam2T);
     }
     // Massage the beam energy in case we had sqrt{s_NN} instead of
     // beam energy.
     if (TMath::Abs(beamEnergy - 1379.8) < 10 && beam1.IsA() && beam2.IsA()) 
       beamEnergy = 3500;
     energy = TMath::Ceil(2*beamEnergy * TMath::Sqrt(Float_t(beam1.z*beam2.z)/
						     (beam1.a*beam2.a)));
     
     const char* fn = FileName();
     std::ofstream* pout = new std::ofstream(fn);
     std::ofstream& out  = *pout;
     out << "# PERIOD:RUN:BEAMENERGY:ENERGY:BEAM1A:BEAM1Z:BEAM2A:BEAM2Z\n" 
	 << period     << ":" 
	 << run        << ":"
	 << beamEnergy << ":" 
	 << energy     << ":" 
	 << beam1.a    << ":"
	 << beam1.z    << ":"
	 << beam2.a    << ":"
	 << beam2.z    << "\n"
	 << "# EOF "   << std::endl;
     pout->close();
     delete pout;
     cdb->SetRun(-1);
     return true;
  }
  /** 
   * Get the value of an environment variable as a unsigned int 
   * 
   * @param envName Enviroment variable name 
   * @param def     Default value 
   *
   * @return As unsigned int, or default
   */
  static UInt_t Env2UInt(const char* envName, UInt_t def)
  {
    TString val(gSystem->Getenv(envName));
    if (val.IsNull()) return def;
    return UInt_t(val.Atoll());
  }
};
GRPData* grp;
void GRP(UInt_t run=0)
{
  grp = new GRPData(run);
}
// 
// EOF
// 



  
 GRP.C:1
 GRP.C:2
 GRP.C:3
 GRP.C:4
 GRP.C:5
 GRP.C:6
 GRP.C:7
 GRP.C:8
 GRP.C:9
 GRP.C:10
 GRP.C:11
 GRP.C:12
 GRP.C:13
 GRP.C:14
 GRP.C:15
 GRP.C:16
 GRP.C:17
 GRP.C:18
 GRP.C:19
 GRP.C:20
 GRP.C:21
 GRP.C:22
 GRP.C:23
 GRP.C:24
 GRP.C:25
 GRP.C:26
 GRP.C:27
 GRP.C:28
 GRP.C:29
 GRP.C:30
 GRP.C:31
 GRP.C:32
 GRP.C:33
 GRP.C:34
 GRP.C:35
 GRP.C:36
 GRP.C:37
 GRP.C:38
 GRP.C:39
 GRP.C:40
 GRP.C:41
 GRP.C:42
 GRP.C:43
 GRP.C:44
 GRP.C:45
 GRP.C:46
 GRP.C:47
 GRP.C:48
 GRP.C:49
 GRP.C:50
 GRP.C:51
 GRP.C:52
 GRP.C:53
 GRP.C:54
 GRP.C:55
 GRP.C:56
 GRP.C:57
 GRP.C:58
 GRP.C:59
 GRP.C:60
 GRP.C:61
 GRP.C:62
 GRP.C:63
 GRP.C:64
 GRP.C:65
 GRP.C:66
 GRP.C:67
 GRP.C:68
 GRP.C:69
 GRP.C:70
 GRP.C:71
 GRP.C:72
 GRP.C:73
 GRP.C:74
 GRP.C:75
 GRP.C:76
 GRP.C:77
 GRP.C:78
 GRP.C:79
 GRP.C:80
 GRP.C:81
 GRP.C:82
 GRP.C:83
 GRP.C:84
 GRP.C:85
 GRP.C:86
 GRP.C:87
 GRP.C:88
 GRP.C:89
 GRP.C:90
 GRP.C:91
 GRP.C:92
 GRP.C:93
 GRP.C:94
 GRP.C:95
 GRP.C:96
 GRP.C:97
 GRP.C:98
 GRP.C:99
 GRP.C:100
 GRP.C:101
 GRP.C:102
 GRP.C:103
 GRP.C:104
 GRP.C:105
 GRP.C:106
 GRP.C:107
 GRP.C:108
 GRP.C:109
 GRP.C:110
 GRP.C:111
 GRP.C:112
 GRP.C:113
 GRP.C:114
 GRP.C:115
 GRP.C:116
 GRP.C:117
 GRP.C:118
 GRP.C:119
 GRP.C:120
 GRP.C:121
 GRP.C:122
 GRP.C:123
 GRP.C:124
 GRP.C:125
 GRP.C:126
 GRP.C:127
 GRP.C:128
 GRP.C:129
 GRP.C:130
 GRP.C:131
 GRP.C:132
 GRP.C:133
 GRP.C:134
 GRP.C:135
 GRP.C:136
 GRP.C:137
 GRP.C:138
 GRP.C:139
 GRP.C:140
 GRP.C:141
 GRP.C:142
 GRP.C:143
 GRP.C:144
 GRP.C:145
 GRP.C:146
 GRP.C:147
 GRP.C:148
 GRP.C:149
 GRP.C:150
 GRP.C:151
 GRP.C:152
 GRP.C:153
 GRP.C:154
 GRP.C:155
 GRP.C:156
 GRP.C:157
 GRP.C:158
 GRP.C:159
 GRP.C:160
 GRP.C:161
 GRP.C:162
 GRP.C:163
 GRP.C:164
 GRP.C:165
 GRP.C:166
 GRP.C:167
 GRP.C:168
 GRP.C:169
 GRP.C:170
 GRP.C:171
 GRP.C:172
 GRP.C:173
 GRP.C:174
 GRP.C:175
 GRP.C:176
 GRP.C:177
 GRP.C:178
 GRP.C:179
 GRP.C:180
 GRP.C:181
 GRP.C:182
 GRP.C:183
 GRP.C:184
 GRP.C:185
 GRP.C:186
 GRP.C:187
 GRP.C:188
 GRP.C:189
 GRP.C:190
 GRP.C:191
 GRP.C:192
 GRP.C:193
 GRP.C:194
 GRP.C:195
 GRP.C:196
 GRP.C:197
 GRP.C:198
 GRP.C:199
 GRP.C:200
 GRP.C:201
 GRP.C:202
 GRP.C:203
 GRP.C:204
 GRP.C:205
 GRP.C:206
 GRP.C:207
 GRP.C:208
 GRP.C:209
 GRP.C:210
 GRP.C:211
 GRP.C:212
 GRP.C:213
 GRP.C:214
 GRP.C:215
 GRP.C:216
 GRP.C:217
 GRP.C:218
 GRP.C:219
 GRP.C:220
 GRP.C:221
 GRP.C:222
 GRP.C:223
 GRP.C:224
 GRP.C:225
 GRP.C:226
 GRP.C:227
 GRP.C:228
 GRP.C:229
 GRP.C:230
 GRP.C:231
 GRP.C:232
 GRP.C:233
 GRP.C:234
 GRP.C:235
 GRP.C:236
 GRP.C:237
 GRP.C:238
 GRP.C:239
 GRP.C:240
 GRP.C:241
 GRP.C:242
 GRP.C:243
 GRP.C:244
 GRP.C:245
 GRP.C:246
 GRP.C:247
 GRP.C:248
 GRP.C:249
 GRP.C:250
 GRP.C:251
 GRP.C:252
 GRP.C:253
 GRP.C:254
 GRP.C:255
 GRP.C:256
 GRP.C:257
 GRP.C:258
 GRP.C:259
 GRP.C:260
 GRP.C:261
 GRP.C:262
 GRP.C:263
 GRP.C:264
 GRP.C:265
 GRP.C:266
 GRP.C:267
 GRP.C:268
 GRP.C:269
 GRP.C:270
 GRP.C:271
 GRP.C:272
 GRP.C:273
 GRP.C:274
 GRP.C:275
 GRP.C:276
 GRP.C:277
 GRP.C:278
 GRP.C:279
 GRP.C:280
 GRP.C:281
 GRP.C:282
 GRP.C:283
 GRP.C:284
 GRP.C:285
 GRP.C:286
 GRP.C:287
 GRP.C:288
 GRP.C:289
 GRP.C:290
 GRP.C:291
 GRP.C:292
 GRP.C:293
 GRP.C:294
 GRP.C:295
 GRP.C:296
 GRP.C:297
 GRP.C:298
 GRP.C:299
 GRP.C:300
 GRP.C:301
 GRP.C:302
 GRP.C:303
 GRP.C:304
 GRP.C:305
 GRP.C:306
 GRP.C:307
 GRP.C:308
 GRP.C:309
 GRP.C:310
 GRP.C:311
 GRP.C:312
 GRP.C:313
 GRP.C:314
 GRP.C:315