ROOT logo
#include "TSystem.h"
#include "TList.h"
#include "TObjString.h"
#include "Riostream.h"
#include "TRegexp.h"
#include "AliMUONVTrackerData.h"
#include "TFile.h"
#include "TKey.h"
#include "TGrid.h"
#include "TGridResult.h"
#include "TUrl.h"
#include "TMath.h"
#include "TFile.h"
#include "TStopwatch.h"
#include "TGridCollection.h"
#include "TROOT.h"
#include "TError.h"
#include "TH1.h"
#include "TMethodCall.h"

void CopyFromRemote(Int_t runNumber, const char* period, const char* pass);
void CopyFromRemote(const TList& files);
TList* GetFileList(Int_t runNumber, const char* period, const char* pass);
void QAMerge(Int_t runNumber, const char* period, const char* pass);
void QAMerge(const TList& files, const char* outputfile);

////______________________________________________________________________________
//AliMUONVTrackerData* GetTrackerData(TDirectory* dir, const char* trackerDataName)
//{
//  AliMUONVTrackerData* trackerData(0x0);
//
//  TIter next(dir->GetListOfKeys());
//  TKey* key;
//  
//  while ( ( key = static_cast<TKey*>(next()) ) && !trackerData )
//  {
//    if ( key->IsFolder() )
//    {
//      trackerData = GetTrackerData(static_cast<TDirectory*>(key->ReadObj()),trackerDataName);
//    }
//    else
//    {
//      TString name(key->GetName());
//      
//      if ( name.Contains(trackerDataName) )
//      {
//        trackerData = dynamic_cast<AliMUONVTrackerData*>(key->ReadObj());
//      }
//    }
//  }
//  
//  return trackerData;
//  
//}
//
////______________________________________________________________________________
//AliMUONVTrackerData* GetTrackerData(const char* filename, const char* trackerDataName)
//{
//  TFile* file = TFile::Open(filename);
//  
//  cout << filename << endl;
//  
//  if (!file) return 0x0;
//
//  AliMUONVTrackerData* trackerData = GetTrackerData(file,trackerDataName);  
//
//  delete file;
//  
//  return trackerData;
//  
//}

////______________________________________________________________________________
//AliMUONVTrackerData* MergeTrackerData(const TList& filelist, const char* trackerDataName)
//{
//  TIter next(&filelist);
//  TObjString* s;
//  
//  s = static_cast<TObjString*>(next());
//  
//  AliMUONVTrackerData* d = GetTrackerData(s->String().Data(),trackerDataName);
//  
//  if (!d)
//  {
//    cout << Form("ERROR : no tracker data found in %s",s->String().Data()) << endl;
//    return 0x0;
//  }
//  
//  AliMUONVTrackerData* merged = static_cast<AliMUONVTrackerData*>(d->Clone(Form("%s-MERGED",trackerDataName)));
//  
//  while ( ( s = static_cast<TObjString*>(next()) ) )
//  {
//    d = GetTrackerData(s->String().Data(),trackerDataName);
//    if (d)
//    {
//      TList list;
//      list.Add(d);
//      cout << "Merging " << s->String().Data() << " " << d->GetName() << " " << d->NumberOfEvents(-1) << endl;
//      
//      merged->Merge(&list);
//      delete d;
//    }
//  }
//  
//  merged->SetName(Form("%s-MERGED-%d",trackerDataName,runNumber));
//  
//  merged->SetTitle(Form("%s merged for run %d",trackerDataName,runNumber));
//  
//
//  return merged;
//}

//______________________________________________________________________________
void GenerateFileList(const char* runlist="philippe.runlist")
{
  if (!gGrid)
  {
    TGrid::Connect("alien://");    
  }
  if (!gGrid) return;
  
  ifstream in(runlist);
  Int_t run;
  
  Int_t n(0);
  
  while ( in >> run )
  {
    TString basedir("/alice/data/2009/LHC09d/");
    
    TString dir(Form("%s%09d/ESDs/pass1/*/Merged.QA.Data.root",basedir.Data(),run));
    
    TGridResult* r = gGrid->Ls(dir.Data());

    Int_t i(0);
    
    while ( r->GetFileName(i) ) 
    {
      cout << "alien://" << r->GetFileNamePath(i) << endl;
      ++i;      
    }
    
    delete r;
    
    ++n;
  }
}

//______________________________________________________________________________
void CopyFromRemote(Int_t runNumber, const char* period, const char* pass)
{
  TList* list = GetFileList(runNumber,period,pass);
  if ( list )
  {
    CopyFromRemote(*list);
  }
  delete list;
}

//______________________________________________________________________________
void CopyFromRemote(const TList& files)
{
  TStopwatch timer;
  
  TIter next(&files);
  TObjString* line;
  
  while ( ( line = static_cast<TObjString*>(next()) ) )
  {
    TUrl url(line->String());

    if ( TString(url.GetProtocol()) == "alien" )
    {
      if (!gGrid)
      {
        TGrid::Connect("alien://");
        if (!gGrid)
        {
          cout << "Cannot get alien connection" << endl;
          return;
        }
      }
    }

    TString file(url.GetFile());

    TString dir(gSystem->DirName(file));

    gSystem->mkdir(dir.Data(),kTRUE);

    if ( gSystem->AccessPathName(file.Data())==kFALSE)
    {
      cout << "Skipping copy of " << file.Data() << " as it already exists" << endl;
    }
    else
    {
      TFile::Cp(line->String().Data(),file.Data());
      if ( line->String().Contains("root_archive.zip") )
      {
        gSystem->Exec(Form("unzip %s -d %s",file.Data(),gSystem->DirName(file.Data())));
        gSystem->Exec(Form("rm %s",file.Data()));
      }
    }
  }
  
  timer.Print();
}

//______________________________________________________________________________
TList* GetFileList(Int_t runNumber, const char* period, const char* pass)
{
  if (!gGrid) TGrid::Connect("alien://");
  if (!gGrid)
  {
    return 0x0;
  }

  Int_t year;
  
  TString speriod(period);
  
  if (!speriod.BeginsWith("LHC"))
  {
    std::cerr << "Period not starting with LHC !" << std::endl;
    return 0x0;
  }
  
  year = 2000 + TString(speriod(3,3)).Atoi();
  
  TString sbasedir(Form("/alice/data/%d/%s/%09d/ESDs/%s",year,period,runNumber,pass));
  
  std::cout << sbasedir.Data() << std::endl;
  
  TString search("Merged.QA.Data.root");
  
  TGridResult* res = gGrid->Query(sbasedir.Data(),search.Data());
  
  Int_t nFiles = res->GetEntries();
  
  nFiles = res->GetEntries();
  
  Long64_t size(0);
  Int_t count(0);
  TList* files(0x0);
  
  for (Int_t i = 0; i < nFiles; ++i)
  {
    Long64_t thisSize = TString(res->GetKey(i,"size")).Atoll();
    
//    TUrl url(res->GetKey(i,"turl"));
    
    if (!files)
    {
      files = new TList;
      files->SetOwner(kTRUE);
    }
    
    files->Add(new TObjString(res->GetKey(i,"turl")));
    
    ++count;
    
    size += thisSize;
  }
  
  std::cout << Form("%d files for a total of %d MB",count,TMath::Nint(size/1024.0/1024)) << std::endl;

  delete res;
  
  return files;
}

//______________________________________________________________________________
void QAMerge(Int_t runNumber, const char* period, const char* pass)
{
  TList* list = GetFileList(runNumber,period,pass);
  if ( list )
  {
    QAMerge(*list,Form("QA.%s.%s.%d.root",period,pass,runNumber));
  }
  delete list;

}

//______________________________________________________________________________
TObject* GetObject(const char* filepath, const char* objectPath)
{
  TFile* f = TFile::Open(filepath);
  
  if (!f)
  {
    std::cerr << "Could not open file " << filepath << std::endl;
    return 0x0;    
  }
  
  TObject* o = f->Get(objectPath);
  
  if (!o)
  {
    std::cout << "Cannot get object " << objectPath << " from " << filepath << std::endl;
    return 0x0;
  }
  
  if ( o->InheritsFrom("TH1") )
  {
    TH1* h = static_cast<TH1*>(o);
    h->SetDirectory(0);
  }
  
  delete f;
  
  return o;
}

//______________________________________________________________________________
TObject* Merge(const TList& files, const char* objectPath)
{
  TIter next(&files);
  TObjString* filename;
  
  filename = static_cast<TObjString*>(next());
  
  TObject* d = GetObject(filename->String().Data(),objectPath);
  
  if (!d)
  {
    cout << Form("ERROR : no object found in %s",filename->String().Data()) << endl;
    return 0x0;
  }
  
  TString oname(gSystem->BaseName(objectPath));
  
  TObject* merged = d->Clone();
  
  TMethodCall callEnv;

  if ( merged->IsA() )
  {
    callEnv.InitWithPrototype(merged->IsA(), "Merge", "TCollection*");
  }
  
  if (!callEnv.IsValid())
  {
    std::cout << "callEnv invalid" << std::endl;
    delete merged;
    return 0x0;
  }

  while ( ( filename = static_cast<TObjString*>(next()) ) )
  {
//    std::cout << filename->String().Data() << " : " << objectPath << std::endl;
    
    d = GetObject(filename->String().Data(),objectPath);
    
    if (!d)
    {
      continue;
    }
    
    TList list;
    list.Add(d);
    callEnv.SetParam((Long_t) (&list));
    callEnv.Execute(merged);
    
    delete d;
  }
  
  return merged;

}

//______________________________________________________________________________
void QAMerge(const TList& files, const char* outputfile)
{
  const char* eventSpecie = "HighMultiplicity";
  
  TList objectsToMerge;
  objectsToMerge.SetOwner(kTRUE);

  objectsToMerge.Add(new TObjString(Form("MUON/Raws/%s/Expert/%s_hTrackerDDLNofEventsSeen",eventSpecie,eventSpecie)));

  objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_RecPoints",eventSpecie,eventSpecie)));
  objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_RecCharges",eventSpecie,eventSpecie)));

  objectsToMerge.Add(new TObjString(Form("MUON/Raws/%s/Expert/%s_RawCharges",eventSpecie,eventSpecie)));

  for ( Int_t i = 1; i <= 10; ++i )
  {
    objectsToMerge.Add(new TObjString(Form("MUON/RecPoints/%s/Expert/%s_hTrackerClusterHitMapForChamber%d",eventSpecie,eventSpecie,i)));
    objectsToMerge.Add(new TObjString(Form("MUON/ESDs/%s/Expert/%s_hESDClusterHitMap%d",eventSpecie,eventSpecie,i)));
  }

  TObjArray output;
  output.SetOwner(kTRUE);

  TIter next(&objectsToMerge);
  TObjString* s;
  
  while ( ( s = static_cast<TObjString*>(next())) )
  {
    output.Add(Merge(files,s->String().Data()));
  }
  
  TFile* f = TFile::Open(outputfile,"recreate");
  
  next.Reset();

  Int_t i(0);
  while ( ( s = static_cast<TObjString*>(next())) )
  {
    TObject* o = output.At(i);
    if (o)
    {
      TString dir = gSystem->DirName(s->String());
      TString file = gSystem->BaseName(s->String());
      TDirectory* tdir = static_cast<TDirectory*>(f->Get(dir.Data()));
      if (!tdir)
      {
        f->mkdir(dir.Data()," ");
        tdir = static_cast<TDirectory*>(f->Get(dir.Data()));
      }
      tdir->cd();
      o->Write(file.Data());
    }
    ++i;
  }

  f->Write();
  
  f->Close();
  
  delete f;
}

//______________________________________________________________________________
void QAMerge(const char* inputfilelist, const char* mergedFile)
{
  if (!gGrid)
  {
    TGrid::Connect("alien://");    
  }
  if (!gGrid) return;
  
  TString sinput(inputfilelist);
  TList filelist;
  filelist.SetOwner(kTRUE);
  
  if (sinput.Contains(".xml"))
  {
    TGridCollection *coll = reinterpret_cast<TGridCollection*>(gROOT->ProcessLine(Form("TAlienCollection::Open(\"%s\");", inputfilelist)));
    if (!coll)
    {
      ::Error("MergeOutput", "Input XML collection empty.");
      return;
    }
    // Iterate grid collection
    while (coll->Next())
    {
      filelist.Add(new TObjString(coll->GetTURL()));
    }
  }
  else
  {
    ifstream in(inputfilelist);
    char filename[1024];

    while (in.getline(filename,1024,'\n'))
    {
      filelist.Add(new TObjString(filename));
    }
  }
    
  if ( filelist.GetEntries()==0 )
  {
    std::cout << "No file to be merged !" << std::endl;
  }
  else
  {
    QAMerge(filelist,mergedFile);
  }
  
  ofstream out;
  out.open("outputs_valid_merge", ios::out);
  out.close();
}

 QAMerge.C:1
 QAMerge.C:2
 QAMerge.C:3
 QAMerge.C:4
 QAMerge.C:5
 QAMerge.C:6
 QAMerge.C:7
 QAMerge.C:8
 QAMerge.C:9
 QAMerge.C:10
 QAMerge.C:11
 QAMerge.C:12
 QAMerge.C:13
 QAMerge.C:14
 QAMerge.C:15
 QAMerge.C:16
 QAMerge.C:17
 QAMerge.C:18
 QAMerge.C:19
 QAMerge.C:20
 QAMerge.C:21
 QAMerge.C:22
 QAMerge.C:23
 QAMerge.C:24
 QAMerge.C:25
 QAMerge.C:26
 QAMerge.C:27
 QAMerge.C:28
 QAMerge.C:29
 QAMerge.C:30
 QAMerge.C:31
 QAMerge.C:32
 QAMerge.C:33
 QAMerge.C:34
 QAMerge.C:35
 QAMerge.C:36
 QAMerge.C:37
 QAMerge.C:38
 QAMerge.C:39
 QAMerge.C:40
 QAMerge.C:41
 QAMerge.C:42
 QAMerge.C:43
 QAMerge.C:44
 QAMerge.C:45
 QAMerge.C:46
 QAMerge.C:47
 QAMerge.C:48
 QAMerge.C:49
 QAMerge.C:50
 QAMerge.C:51
 QAMerge.C:52
 QAMerge.C:53
 QAMerge.C:54
 QAMerge.C:55
 QAMerge.C:56
 QAMerge.C:57
 QAMerge.C:58
 QAMerge.C:59
 QAMerge.C:60
 QAMerge.C:61
 QAMerge.C:62
 QAMerge.C:63
 QAMerge.C:64
 QAMerge.C:65
 QAMerge.C:66
 QAMerge.C:67
 QAMerge.C:68
 QAMerge.C:69
 QAMerge.C:70
 QAMerge.C:71
 QAMerge.C:72
 QAMerge.C:73
 QAMerge.C:74
 QAMerge.C:75
 QAMerge.C:76
 QAMerge.C:77
 QAMerge.C:78
 QAMerge.C:79
 QAMerge.C:80
 QAMerge.C:81
 QAMerge.C:82
 QAMerge.C:83
 QAMerge.C:84
 QAMerge.C:85
 QAMerge.C:86
 QAMerge.C:87
 QAMerge.C:88
 QAMerge.C:89
 QAMerge.C:90
 QAMerge.C:91
 QAMerge.C:92
 QAMerge.C:93
 QAMerge.C:94
 QAMerge.C:95
 QAMerge.C:96
 QAMerge.C:97
 QAMerge.C:98
 QAMerge.C:99
 QAMerge.C:100
 QAMerge.C:101
 QAMerge.C:102
 QAMerge.C:103
 QAMerge.C:104
 QAMerge.C:105
 QAMerge.C:106
 QAMerge.C:107
 QAMerge.C:108
 QAMerge.C:109
 QAMerge.C:110
 QAMerge.C:111
 QAMerge.C:112
 QAMerge.C:113
 QAMerge.C:114
 QAMerge.C:115
 QAMerge.C:116
 QAMerge.C:117
 QAMerge.C:118
 QAMerge.C:119
 QAMerge.C:120
 QAMerge.C:121
 QAMerge.C:122
 QAMerge.C:123
 QAMerge.C:124
 QAMerge.C:125
 QAMerge.C:126
 QAMerge.C:127
 QAMerge.C:128
 QAMerge.C:129
 QAMerge.C:130
 QAMerge.C:131
 QAMerge.C:132
 QAMerge.C:133
 QAMerge.C:134
 QAMerge.C:135
 QAMerge.C:136
 QAMerge.C:137
 QAMerge.C:138
 QAMerge.C:139
 QAMerge.C:140
 QAMerge.C:141
 QAMerge.C:142
 QAMerge.C:143
 QAMerge.C:144
 QAMerge.C:145
 QAMerge.C:146
 QAMerge.C:147
 QAMerge.C:148
 QAMerge.C:149
 QAMerge.C:150
 QAMerge.C:151
 QAMerge.C:152
 QAMerge.C:153
 QAMerge.C:154
 QAMerge.C:155
 QAMerge.C:156
 QAMerge.C:157
 QAMerge.C:158
 QAMerge.C:159
 QAMerge.C:160
 QAMerge.C:161
 QAMerge.C:162
 QAMerge.C:163
 QAMerge.C:164
 QAMerge.C:165
 QAMerge.C:166
 QAMerge.C:167
 QAMerge.C:168
 QAMerge.C:169
 QAMerge.C:170
 QAMerge.C:171
 QAMerge.C:172
 QAMerge.C:173
 QAMerge.C:174
 QAMerge.C:175
 QAMerge.C:176
 QAMerge.C:177
 QAMerge.C:178
 QAMerge.C:179
 QAMerge.C:180
 QAMerge.C:181
 QAMerge.C:182
 QAMerge.C:183
 QAMerge.C:184
 QAMerge.C:185
 QAMerge.C:186
 QAMerge.C:187
 QAMerge.C:188
 QAMerge.C:189
 QAMerge.C:190
 QAMerge.C:191
 QAMerge.C:192
 QAMerge.C:193
 QAMerge.C:194
 QAMerge.C:195
 QAMerge.C:196
 QAMerge.C:197
 QAMerge.C:198
 QAMerge.C:199
 QAMerge.C:200
 QAMerge.C:201
 QAMerge.C:202
 QAMerge.C:203
 QAMerge.C:204
 QAMerge.C:205
 QAMerge.C:206
 QAMerge.C:207
 QAMerge.C:208
 QAMerge.C:209
 QAMerge.C:210
 QAMerge.C:211
 QAMerge.C:212
 QAMerge.C:213
 QAMerge.C:214
 QAMerge.C:215
 QAMerge.C:216
 QAMerge.C:217
 QAMerge.C:218
 QAMerge.C:219
 QAMerge.C:220
 QAMerge.C:221
 QAMerge.C:222
 QAMerge.C:223
 QAMerge.C:224
 QAMerge.C:225
 QAMerge.C:226
 QAMerge.C:227
 QAMerge.C:228
 QAMerge.C:229
 QAMerge.C:230
 QAMerge.C:231
 QAMerge.C:232
 QAMerge.C:233
 QAMerge.C:234
 QAMerge.C:235
 QAMerge.C:236
 QAMerge.C:237
 QAMerge.C:238
 QAMerge.C:239
 QAMerge.C:240
 QAMerge.C:241
 QAMerge.C:242
 QAMerge.C:243
 QAMerge.C:244
 QAMerge.C:245
 QAMerge.C:246
 QAMerge.C:247
 QAMerge.C:248
 QAMerge.C:249
 QAMerge.C:250
 QAMerge.C:251
 QAMerge.C:252
 QAMerge.C:253
 QAMerge.C:254
 QAMerge.C:255
 QAMerge.C:256
 QAMerge.C:257
 QAMerge.C:258
 QAMerge.C:259
 QAMerge.C:260
 QAMerge.C:261
 QAMerge.C:262
 QAMerge.C:263
 QAMerge.C:264
 QAMerge.C:265
 QAMerge.C:266
 QAMerge.C:267
 QAMerge.C:268
 QAMerge.C:269
 QAMerge.C:270
 QAMerge.C:271
 QAMerge.C:272
 QAMerge.C:273
 QAMerge.C:274
 QAMerge.C:275
 QAMerge.C:276
 QAMerge.C:277
 QAMerge.C:278
 QAMerge.C:279
 QAMerge.C:280
 QAMerge.C:281
 QAMerge.C:282
 QAMerge.C:283
 QAMerge.C:284
 QAMerge.C:285
 QAMerge.C:286
 QAMerge.C:287
 QAMerge.C:288
 QAMerge.C:289
 QAMerge.C:290
 QAMerge.C:291
 QAMerge.C:292
 QAMerge.C:293
 QAMerge.C:294
 QAMerge.C:295
 QAMerge.C:296
 QAMerge.C:297
 QAMerge.C:298
 QAMerge.C:299
 QAMerge.C:300
 QAMerge.C:301
 QAMerge.C:302
 QAMerge.C:303
 QAMerge.C:304
 QAMerge.C:305
 QAMerge.C:306
 QAMerge.C:307
 QAMerge.C:308
 QAMerge.C:309
 QAMerge.C:310
 QAMerge.C:311
 QAMerge.C:312
 QAMerge.C:313
 QAMerge.C:314
 QAMerge.C:315
 QAMerge.C:316
 QAMerge.C:317
 QAMerge.C:318
 QAMerge.C:319
 QAMerge.C:320
 QAMerge.C:321
 QAMerge.C:322
 QAMerge.C:323
 QAMerge.C:324
 QAMerge.C:325
 QAMerge.C:326
 QAMerge.C:327
 QAMerge.C:328
 QAMerge.C:329
 QAMerge.C:330
 QAMerge.C:331
 QAMerge.C:332
 QAMerge.C:333
 QAMerge.C:334
 QAMerge.C:335
 QAMerge.C:336
 QAMerge.C:337
 QAMerge.C:338
 QAMerge.C:339
 QAMerge.C:340
 QAMerge.C:341
 QAMerge.C:342
 QAMerge.C:343
 QAMerge.C:344
 QAMerge.C:345
 QAMerge.C:346
 QAMerge.C:347
 QAMerge.C:348
 QAMerge.C:349
 QAMerge.C:350
 QAMerge.C:351
 QAMerge.C:352
 QAMerge.C:353
 QAMerge.C:354
 QAMerge.C:355
 QAMerge.C:356
 QAMerge.C:357
 QAMerge.C:358
 QAMerge.C:359
 QAMerge.C:360
 QAMerge.C:361
 QAMerge.C:362
 QAMerge.C:363
 QAMerge.C:364
 QAMerge.C:365
 QAMerge.C:366
 QAMerge.C:367
 QAMerge.C:368
 QAMerge.C:369
 QAMerge.C:370
 QAMerge.C:371
 QAMerge.C:372
 QAMerge.C:373
 QAMerge.C:374
 QAMerge.C:375
 QAMerge.C:376
 QAMerge.C:377
 QAMerge.C:378
 QAMerge.C:379
 QAMerge.C:380
 QAMerge.C:381
 QAMerge.C:382
 QAMerge.C:383
 QAMerge.C:384
 QAMerge.C:385
 QAMerge.C:386
 QAMerge.C:387
 QAMerge.C:388
 QAMerge.C:389
 QAMerge.C:390
 QAMerge.C:391
 QAMerge.C:392
 QAMerge.C:393
 QAMerge.C:394
 QAMerge.C:395
 QAMerge.C:396
 QAMerge.C:397
 QAMerge.C:398
 QAMerge.C:399
 QAMerge.C:400
 QAMerge.C:401
 QAMerge.C:402
 QAMerge.C:403
 QAMerge.C:404
 QAMerge.C:405
 QAMerge.C:406
 QAMerge.C:407
 QAMerge.C:408
 QAMerge.C:409
 QAMerge.C:410
 QAMerge.C:411
 QAMerge.C:412
 QAMerge.C:413
 QAMerge.C:414
 QAMerge.C:415
 QAMerge.C:416
 QAMerge.C:417
 QAMerge.C:418
 QAMerge.C:419
 QAMerge.C:420
 QAMerge.C:421
 QAMerge.C:422
 QAMerge.C:423
 QAMerge.C:424
 QAMerge.C:425
 QAMerge.C:426
 QAMerge.C:427
 QAMerge.C:428
 QAMerge.C:429
 QAMerge.C:430
 QAMerge.C:431
 QAMerge.C:432
 QAMerge.C:433
 QAMerge.C:434
 QAMerge.C:435
 QAMerge.C:436
 QAMerge.C:437
 QAMerge.C:438
 QAMerge.C:439
 QAMerge.C:440
 QAMerge.C:441
 QAMerge.C:442
 QAMerge.C:443
 QAMerge.C:444
 QAMerge.C:445
 QAMerge.C:446
 QAMerge.C:447
 QAMerge.C:448
 QAMerge.C:449
 QAMerge.C:450
 QAMerge.C:451
 QAMerge.C:452
 QAMerge.C:453
 QAMerge.C:454
 QAMerge.C:455
 QAMerge.C:456
 QAMerge.C:457
 QAMerge.C:458
 QAMerge.C:459
 QAMerge.C:460
 QAMerge.C:461
 QAMerge.C:462
 QAMerge.C:463
 QAMerge.C:464
 QAMerge.C:465
 QAMerge.C:466
 QAMerge.C:467
 QAMerge.C:468
 QAMerge.C:469
 QAMerge.C:470
 QAMerge.C:471
 QAMerge.C:472
 QAMerge.C:473
 QAMerge.C:474
 QAMerge.C:475
 QAMerge.C:476
 QAMerge.C:477
 QAMerge.C:478
 QAMerge.C:479
 QAMerge.C:480
 QAMerge.C:481
 QAMerge.C:482
 QAMerge.C:483
 QAMerge.C:484
 QAMerge.C:485
 QAMerge.C:486