Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / MUON / AliMUONAlignmentTask.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 // $Id$
17
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONAlignmentTask
20 /// AliAnalysisTask to align the MUON spectrometer.
21 /// The Task reads as input ESDs and feeds the MUONTracks to AliMUONAlignment.
22 /// The alignment itself is performed by AliMillepede.
23 /// A OCDB entry is written with the alignment parameters.
24 /// A list of graph are written to monitor the alignment parameters.
25 ///
26 /// \author Javier Castillo, CEA/Saclay - Irfu/SPhN
27 //-----------------------------------------------------------------------------
28
29 // this class header must always come first
30 #include "AliMUONAlignmentTask.h"
31
32 // local header must come before system headers
33 #include "AliAnalysisManager.h"
34 #include "AliAODInputHandler.h"
35 #include "AliAODHandler.h"
36 #include "AliAODEvent.h"
37 #include "AliAODHeader.h"
38 #include "AliESDInputHandler.h"
39 #include "AliESDEvent.h"
40 #include "AliESDMuonTrack.h"
41 #include "AliMagF.h"
42 #include "AliCDBStorage.h"
43 #include "AliCDBManager.h"
44 #include "AliGRPManager.h"
45 #include "AliCDBMetaData.h"
46 #include "AliCDBId.h"
47 #include "AliGeomManager.h"
48
49 #include "AliMpCDB.h"
50 #include "AliMUONCDB.h"
51 #include "AliMUONAlignment.h"
52 #include "AliMUONTrack.h"
53 #include "AliMUONTrackExtrap.h"
54 #include "AliMUONTrackParam.h"
55 #include "AliMUONGeometryTransformer.h"
56 #include "AliMUONESDInterface.h"
57
58 // system headers
59 #include <fstream>
60 #include <TString.h>
61 #include <TError.h>
62 #include <TGraphErrors.h>
63 #include <TTree.h>
64 #include <TChain.h>
65 #include <TClonesArray.h>
66 #include <TGeoGlobalMagField.h>
67 #include <TGeoManager.h>
68 #include <Riostream.h>
69
70 ///\cond CLASSIMP
71 ClassImp(AliMUONAlignmentTask)
72 ///\endcond
73
74 //________________________________________________________________________
75 AliMUONAlignmentTask::AliMUONAlignmentTask(const char *name, const char *newalignocdb, const char *oldalignocdb, const char *defaultocdb, const char *geofilename):
76   AliAnalysisTaskSE(name),
77   fReadRecords( kFALSE ),
78   fWriteRecords( kFALSE ),
79   fDoAlignment( kTRUE ),
80   fAlign(0x0),
81   fGeoFilename(geofilename),
82   fDefaultStorage(defaultocdb),
83   fOldAlignStorage(oldalignocdb),
84   fNewAlignStorage(newalignocdb),
85   fOldGeoTransformer(NULL),
86   fNewGeoTransformer(NULL),
87   fLoadOCDBOnce(kFALSE),
88   fOCDBLoaded(kFALSE),
89   fTrackTot(0),
90   fTrackOk(0),
91   fLastRunNumber(-1),
92   fMSDEx(0x0),
93   fMSDEy(0x0),
94   fMSDEz(0x0),
95   fMSDEp(0x0),
96   fList(0x0),
97   fRecords(0x0),
98   fRecordCount(0)
99 {
100   /// Default Constructor
101   // Define input and output slots here
102   // Input slot #0 works with a TChain
103   DefineInput(0, TChain::Class());
104
105   // Output slot #0 writes NTuple/histos into a TList
106   DefineOutput(1, TList::Class());
107
108   // initialize parameters ...
109   for(Int_t k=0;k<4*156;k++)
110   {
111     fParameters[k]=0.;
112     fErrors[k]=0.;
113     fPulls[k]=0.;
114   }
115
116   fOldGeoTransformer = new AliMUONGeometryTransformer();
117
118 }
119
120 //________________________________________________________________________
121 AliMUONAlignmentTask::AliMUONAlignmentTask(const AliMUONAlignmentTask& other):
122   AliAnalysisTaskSE(other),
123   fReadRecords( other.fReadRecords ),
124   fWriteRecords( other.fWriteRecords ),
125   fDoAlignment( other.fDoAlignment ),
126   fAlign( other.fAlign ),
127   fGeoFilename( other.fGeoFilename ),
128   fDefaultStorage( other.fDefaultStorage ),
129   fOldAlignStorage( other.fOldAlignStorage ),
130   fNewAlignStorage( other.fNewAlignStorage ),
131   fOldGeoTransformer( other.fOldGeoTransformer ),
132   fNewGeoTransformer( other.fNewGeoTransformer ),
133   fLoadOCDBOnce( other.fLoadOCDBOnce ),
134   fOCDBLoaded( other.fOCDBLoaded ),
135   fTrackTot( other.fTrackTot ),
136   fTrackOk( other.fTrackOk ),
137   fLastRunNumber( other.fLastRunNumber ),
138   fMSDEx( other.fMSDEx ),
139   fMSDEy( other.fMSDEy ),
140   fMSDEz( other.fMSDEz ),
141   fMSDEp( other.fMSDEp ),
142   fList( other.fList ),
143   fRecords( other.fRecords ),
144   fRecordCount( other.fRecordCount )
145 {
146
147   // initialize parameters
148   for(Int_t k=0;k<4*156;k++)
149   {
150
151     fParameters[k]=other.fParameters[k];
152     fErrors[k]=other.fErrors[k];
153     fPulls[k]=other.fPulls[k];
154
155   }
156
157 }
158
159 //________________________________________________________________________
160 AliMUONAlignmentTask& AliMUONAlignmentTask::operator=(const AliMUONAlignmentTask& other)
161 {
162   /// Assignment
163   if(&other == this) return *this;
164   AliAnalysisTaskSE::operator=(other);
165
166   fReadRecords = other.fReadRecords;
167   fWriteRecords = other.fWriteRecords;
168   fDoAlignment = other.fDoAlignment;
169
170   // this breaks in destructor
171   fAlign = other.fAlign;
172
173   fGeoFilename = other.fGeoFilename;
174   fDefaultStorage = other.fDefaultStorage;
175   fOldAlignStorage = other.fOldAlignStorage;
176   fNewAlignStorage = other.fNewAlignStorage;
177
178   // this breaks in destructor
179   fOldGeoTransformer = other.fOldGeoTransformer;
180   fNewGeoTransformer = other.fNewGeoTransformer;
181
182   fLoadOCDBOnce = other.fLoadOCDBOnce;
183   fOCDBLoaded = other.fOCDBLoaded;
184   fTrackTot = other.fTrackTot;
185   fTrackOk = other.fTrackOk;
186   fLastRunNumber = other.fLastRunNumber;
187   fMSDEx = other.fMSDEx;
188   fMSDEy = other.fMSDEy;
189   fMSDEz = other.fMSDEz;
190   fMSDEp = other.fMSDEp;
191   fList = other.fList;
192   fRecords = other.fRecords;
193   fRecordCount = other.fRecordCount;
194
195   // initialize parameters ...
196   for( Int_t k=0; k<4*156; ++k)
197   {
198
199     fParameters[k]=other.fParameters[k];
200     fErrors[k]=other.fErrors[k];
201     fPulls[k]=other.fPulls[k];
202
203   }
204
205   return *this;
206 }
207
208 //________________________________________________________________________
209 AliMUONAlignmentTask::~AliMUONAlignmentTask()
210 {
211   /*
212   it is safe to delete NULL pointers, so
213   there is no need to test their validity here.
214   However, it crashes here, because of incorrect assignment operator
215   and copy constructor, resulting in double deletion of objects.
216   Would require deep copy instead.
217   */
218   delete fAlign;
219   delete fOldGeoTransformer;
220   delete fNewGeoTransformer;
221 }
222
223 //________________________________________________________________________
224 void AliMUONAlignmentTask::LocalInit()
225 {
226   /// Local initialization, called once per task on the client machine
227   /// where the analysis train is assembled
228
229   // print configuration
230   AliInfo( Form( "fReadRecords: %s", (fReadRecords ? "kTRUE":"kFALSE" ) ) );
231   AliInfo( Form( "fWriteRecords: %s", (fWriteRecords ? "kTRUE":"kFALSE" ) ) );
232   AliInfo( Form( "fDoAlignment: %s", (fDoAlignment ? "kTRUE":"kFALSE" ) ) );
233
234   // consistency checks between flags
235   /* need at least one of the flags set to true */
236   if( !( fReadRecords || fWriteRecords || fDoAlignment ) )
237   { AliFatal( "Need at least one of the three flags fReadRecords, fWriteRecords and fDoAlignment set to kTRUE" ); }
238
239   /* cannot read and write records at the same time */
240   if( fReadRecords && fWriteRecords )
241   { AliFatal( "Cannot set both fReadRecords and fWriteRecords to kTRUE at the same time" ); }
242
243   /* must run alignment when reading records */
244   if( fReadRecords && !fDoAlignment )
245   {
246
247     AliInfo( "Automatically setting fDoAlignment to kTRUE because fReadRecords is kTRUE" );
248     SetDoAlignment( kTRUE );
249
250   }
251
252   // Set initial values here, good guess may help convergence
253   // St 1
254   //  Int_t iPar = 0;
255   //  fParameters[iPar++] =  0.010300 ;  fParameters[iPar++] =  0.010600 ;  fParameters[iPar++] =  0.000396 ;
256
257   fAlign = new AliMUONAlignment();
258   fAlign->InitGlobalParameters(fParameters);
259
260 //  AliCDBManager::Instance()->Print();
261 //
262 //  fAlign->SetGeometryTransformer(fOldGeoTransformer);
263
264   // Do alignment with magnetic field off
265   fAlign->SetBFieldOn(kFALSE);
266
267   // Set tracking station to use
268   //  Bool_t bStOnOff[5] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
269   Bool_t bChOnOff[10] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
270
271   // Set degrees of freedom to align (see AliMUONAlignment)
272   fAlign->AllowVariations(bChOnOff);
273
274   // Set expected resolution (see AliMUONAlignment)
275   fAlign->SetSigmaXY(0.15,0.10);
276
277   // Fix parameters or add constraints here
278   //   for (Int_t iSt=0; iSt<5; iSt++)
279   //     if (!bStOnOff[iSt]) fAlign->FixStation(iSt+1);
280   for (Int_t iCh=0; iCh<10; iCh++)
281     if (!bChOnOff[iCh]) fAlign->FixChamber(iCh+1);
282
283   // Left and right sides of the detector are independent, one can choose to align
284   // only one side
285   Bool_t bSpecLROnOff[2] = {kTRUE,kTRUE};
286   fAlign->FixHalfSpectrometer(bChOnOff,bSpecLROnOff);
287
288   fAlign->SetChOnOff(bChOnOff);
289   fAlign->SetSpecLROnOff(bChOnOff);
290
291     // Here we can fix some detection elements
292   //  fAlign->FixDetElem(908);
293         //  fAlign->FixDetElem(1012);
294         fAlign->FixDetElem(608);
295
296   // Set predifined global constrains: X, Y, P, XvsZ, YvsZ, PvsZ, XvsY, YvsY, PvsY
297 //   Bool_t bVarXYT[9] = {kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE,kTRUE};
298 //   Bool_t bDetTLBR[4] = {kFALSE,kTRUE,kFALSE,kTRUE};
299   //  fAlign->AddConstraints(bChOnOff,bVarXYT,bDetTLBR,bSpecLROnOff);
300
301 }
302
303 //________________________________________________________________________
304 void AliMUONAlignmentTask::UserCreateOutputObjects()
305 {
306
307   if( fDoAlignment )
308   {
309
310     // Creating graphs
311     fMSDEx = new TGraphErrors(156);
312     fMSDEy = new TGraphErrors(156);
313     fMSDEz = new TGraphErrors(156);
314     fMSDEp = new TGraphErrors(156);
315
316     // Add Ntuples to the list
317     fList = new TList();
318     fList->Add(fMSDEx);
319     fList->Add(fMSDEy);
320     fList->Add(fMSDEz);
321     fList->Add(fMSDEp);
322
323     fList->SetOwner(kTRUE);
324     PostData(1, fList);
325   }
326
327   // connect AOD output
328   if( fWriteRecords )
329   {
330     AliAODHandler* handler = dynamic_cast<AliAODHandler*>( AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler() );
331     if( handler )
332     {
333
334       // get AOD output handler and add Branch
335       fRecords = new TClonesArray( "AliMUONAlignmentTrackRecord", 0 );
336       fRecords->SetName( "records" );
337       handler->AddBranch("TClonesArray", &fRecords);
338
339       fRecordCount = 0;
340
341     } else AliInfo( "Error: invalid output event handler" );
342
343   }
344
345 }
346
347 //________________________________________________________________________
348 void AliMUONAlignmentTask::UserExec(Option_t *)
349 {
350   // print configuration
351 //  AliInfo( Form( "fReadRecords: %s", (fReadRecords ? "kTRUE":"kFALSE" ) ) );
352 //  AliInfo( Form( "fWriteRecords: %s", (fWriteRecords ? "kTRUE":"kFALSE" ) ) );
353 //  AliInfo( Form( "fDoAlignment: %s", (fDoAlignment ? "kTRUE":"kFALSE" ) ) );
354   // clear array
355   if( fWriteRecords && fRecords )
356   {
357     fRecords->Clear();
358     fRecordCount = 0;
359   }
360
361   // local track parameters
362   Double_t trackParams[8] = {0.,0.,0.,0.,0.,0.,0.,0.};
363
364   if( fReadRecords ) {
365
366     AliAODEvent* lAOD( dynamic_cast<AliAODEvent*>(InputEvent() ) );
367
368     // check AOD
369     if( !lAOD )
370     {
371       AliInfo("Error: AOD event not available");
372       return;
373     }
374
375     // read records
376     TClonesArray* records = static_cast<TClonesArray*>( lAOD->FindListObject( "records" ) );
377     if( !records )
378     {
379       AliInfo( "Unable to read object name \"records\"" );
380       return;
381     }
382
383     // get number of records and print
384     const Int_t lRecordsCount( records->GetEntriesFast() );
385     fTrackTot += lRecordsCount;
386
387     // loop over records
388     for( Int_t index = 0; index < lRecordsCount; ++index )
389     {
390
391       if( AliMUONAlignmentTrackRecord* record = dynamic_cast<AliMUONAlignmentTrackRecord*>( records->UncheckedAt(index) ) )
392       {
393
394         fAlign->ProcessTrack( record, fDoAlignment );
395         if( fDoAlignment )
396         { fAlign->LocalFit( fTrackOk++, trackParams, 0 ); }
397
398       } else AliInfo( Form( "Invalid record at %i", index ) );
399
400     }
401
402   } else {
403
404     /// Main loop, called for each event
405     AliESDEvent* lESD( dynamic_cast<AliESDEvent*>(InputEvent()) );
406
407     // check ESD
408     if( !lESD )
409     {
410       AliInfo("Error: ESD event not available");
411       return;
412     }
413
414 // HUGO: Comment out check on run number, to be able to run on MC
415 //     if (!lESD->GetRunNumber())
416 //     {
417 //       AliInfo( Form( "Current Run Number: %i", lESD->GetRunNumber() ) );
418 //       return;
419 //     }
420
421     //  if (lESD->GetRunNumber()!=fLastRunNumber){
422     //    fLastRunNumber = lESD->GetRunNumber();
423     //    Prepare(fGeoFilename.Data(),fDefaultOCDB.Data(),fMisAlignOCDB.Data());
424     //  }
425
426     Int_t nTracks = Int_t(lESD->GetNumberOfMuonTracks());
427 //    cout << " there are " << nTracks << " tracks" << endl;
428     for( Int_t iTrack = 0; iTrack < nTracks; iTrack++ )
429     {
430
431       AliESDMuonTrack* esdTrack = lESD->GetMuonTrack(iTrack);
432       if (!esdTrack->ContainTrackerData()) continue;
433       if (!esdTrack->ContainTriggerData()) continue;
434
435       Double_t invBenMom = esdTrack->GetInverseBendingMomentum();
436       //     fInvBenMom->Fill(invBenMom);
437       //     fBenMom->Fill(1./invBenMom);
438       if (TMath::Abs(invBenMom)<=1.04)
439       {
440
441         AliMUONTrack track;
442         AliMUONESDInterface::ESDToMUON(*esdTrack, track);
443
444         // process track and retrieve corresponding records, for storage
445         const AliMUONAlignmentTrackRecord* lRecords( fAlign->ProcessTrack( &track, fDoAlignment ) );
446
447         // do the fit, if required
448         if( fDoAlignment ) fAlign->LocalFit(fTrackOk++,trackParams,0);
449         else fTrackOk++;
450
451         // store in array
452         if( fWriteRecords && fRecords )
453         {                                       
454           new((*fRecords)[fRecordCount]) AliMUONAlignmentTrackRecord( *lRecords );
455           ++fRecordCount;
456         }
457
458       }                 
459                         
460       ++fTrackTot;
461
462       if(!(fTrackTot%1000))
463       { AliInfo( Form( "Processed %i Tracks and %i were fitted.", fTrackTot, fTrackOk ) ); }
464
465 //      cout << "Processed " << fTrackTot << " Tracks." << endl;
466       // Post final data. Write histo list to a file with option "RECREATE"
467       PostData(1,fList);
468
469     }
470
471     // save AOD
472     if( fWriteRecords && fRecordCount > 0 ) { 
473       AliAODHandler* handler = dynamic_cast<AliAODHandler*>( AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler() );
474       if( handler )
475         {
476 //                      printf("handler: %p\n",handler);
477                         AliAODEvent* aod = handler->GetAOD();
478 //                      printf("aod: %p\n",aod);
479                         AliAODHeader* header = aod->GetHeader();
480 //                      printf("header: %p\n",header);
481                         header->SetRunNumber(lESD->GetRunNumber());
482 //                      printf("RunNumber: %d\n",lESD->GetRunNumber());
483                         AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler()->SetFillAOD(kTRUE);
484         } else AliInfo( "Error: invalid output event handler" );
485     }
486
487   }
488
489 }
490
491 //________________________________________________________________________
492 void AliMUONAlignmentTask::Terminate(const Option_t*)
493 { return; }
494
495 //________________________________________________________________________
496 void AliMUONAlignmentTask::FinishTaskOutput()
497 {
498
499   /// Called once per task on the client machine at the end of the analysis.
500   AliInfo( Form( "Processed %i tracks.", fTrackTot ) );
501   AliInfo( Form( "Accepted %i tracks.", fTrackOk ) );
502
503   // stop here if no alignment is to be performed
504   if( !fDoAlignment ) return;
505
506   AliLog::SetGlobalLogLevel(AliLog::kInfo);
507
508   // Perform global fit
509   fAlign->GlobalFit(fParameters,fErrors,fPulls);
510
511 //   // Update pointers reading them from the output slot
512 //   fList = (TList*)GetOutputData(0);
513 //   fMSDEx = (TGraphErrors*)fList->At(0);
514 //   fMSDEy = (TGraphErrors*)fList->At(1);
515 //   fMSDEz = (TGraphErrors*)fList->At(2);
516 //   fMSDEp = (TGraphErrors*)fList->At(3);
517
518   // Store results
519   Double_t DEid[156] = {0};
520   Double_t MSDEx[156] = {0};
521   Double_t MSDEy[156] = {0};
522   Double_t MSDEz[156] = {0};
523   Double_t MSDEp[156] = {0};
524   Double_t DEidErr[156] = {0};
525   Double_t MSDExErr[156] = {0};
526   Double_t MSDEyErr[156] = {0};
527   Double_t MSDEzErr[156] = {0};
528   Double_t MSDEpErr[156] = {0};
529   Int_t lNDetElem = 4*2+4*2+18*2+26*2+26*2;
530   Int_t lNDetElemCh[10] = {4,4,4,4,18,18,26,26,26,26};
531   // Int_t lSNDetElemCh[10] = {4,8,12,16,34,52,78,104,130,156};
532   Int_t idOffset = 0; // 400
533   Int_t lSDetElemCh = 0;
534   for(Int_t iDE=0; iDE<lNDetElem; iDE++)
535   {
536
537     DEidErr[iDE] = 0.;
538     DEid[iDE] = idOffset+100;
539     DEid[iDE] += iDE;
540     lSDetElemCh = 0;
541     for(Int_t iCh=0; iCh<9; iCh++)
542     {
543       lSDetElemCh += lNDetElemCh[iCh];
544
545       if (iDE>=lSDetElemCh)
546       {
547         DEid[iDE] += 100;
548         DEid[iDE] -= lNDetElemCh[iCh];
549       }
550
551     }
552
553     MSDEx[iDE]=fParameters[4*iDE+0];
554     MSDEy[iDE]=fParameters[4*iDE+1];
555     MSDEz[iDE]=fParameters[4*iDE+3];
556     MSDEp[iDE]=fParameters[4*iDE+2];
557     MSDExErr[iDE]=(Double_t)fAlign->GetParError(4*iDE+0);
558     MSDEyErr[iDE]=(Double_t)fAlign->GetParError(4*iDE+1);
559     MSDEzErr[iDE]=(Double_t)fAlign->GetParError(4*iDE+3);
560     MSDEpErr[iDE]=(Double_t)fAlign->GetParError(4*iDE+2);
561     fMSDEx->SetPoint(iDE,DEid[iDE],fParameters[4*iDE+0]);
562     fMSDEx->SetPointError(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(4*iDE+0));
563     fMSDEy->SetPoint(iDE,DEid[iDE],fParameters[4*iDE+1]);
564     fMSDEy->SetPointError(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(4*iDE+1));
565     fMSDEz->SetPoint(iDE,DEid[iDE],fParameters[4*iDE+3]);
566     fMSDEz->SetPointError(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(4*iDE+3));
567     fMSDEp->SetPoint(iDE,DEid[iDE],fParameters[4*iDE+2]);
568     fMSDEp->SetPointError(iDE,DEidErr[iDE],(Double_t)fAlign->GetParError(4*iDE+2));
569
570   }
571
572   // Post final data. Write histo list to a file with option "RECREATE"
573   PostData(1,fList);
574
575   // HUGO: stop here to test reproducibility
576         //  return;
577
578   // Re Align
579   fNewGeoTransformer = fAlign->ReAlign(fOldGeoTransformer,fParameters,true);
580   //  newTransform->WriteTransformations("transform2ReAlign.dat");
581
582   // Generate realigned data in local cdb
583   const TClonesArray* array = fNewGeoTransformer->GetMisAlignmentData();
584
585   // 100 mum residual resolution for chamber misalignments?
586   fAlign->SetAlignmentResolution(array,-1,0.01,0.01,0.004,0.003);
587
588   // CDB manager
589   AliLog::SetGlobalDebugLevel(2);
590   AliCDBManager* cdbm = AliCDBManager::Instance();
591   // cdbManager->SetDefaultStorage(fDefaultOCDB.Data());
592
593         // recover default storage full name (raw:// cannot be used to set specific storage)
594         TString defaultStorage(cdbm->GetDefaultStorage()->GetType());
595         if (defaultStorage == "alien") defaultStorage += Form("://folder=%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
596         else defaultStorage += Form("://%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
597
598         if (fOldAlignStorage != "none") cdbm->UnloadFromCache("MUON/Align/Data");
599         if (!fNewAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fNewAlignStorage.Data());
600         //      else cdbm->SetSpecificStorage("MUON/Align/Data",fDefaultStorage.Data());
601         else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
602
603
604   AliCDBMetaData* cdbData = new AliCDBMetaData();
605   cdbData->SetResponsible("Dimuon Offline project");
606   cdbData->SetComment("MUON alignment objects with residual misalignment");
607   AliCDBId id("MUON/Align/Data", 0, AliCDBRunRange::Infinity());
608   cdbm->Put(const_cast<TClonesArray*>(array), id, cdbData);
609
610         gSystem->Exec("cp -a ReAlignOCDB/MUON/Align/Data/Run0_999999999_v0_s0.root Run0_999999999_v0_s0.root");
611         gSystem->Exec("ls -l");
612
613 }
614
615 //________________________________________________________________________
616 void AliMUONAlignmentTask::NotifyRun()
617 {
618   
619   if (fOCDBLoaded && fLoadOCDBOnce) { AliError(Form("OCDB already loaded %d %d",fOCDBLoaded,fLoadOCDBOnce));
620     return;
621   }
622
623   AliCDBManager* cdbm = AliCDBManager::Instance();
624   cdbm->SetDefaultStorage(fDefaultStorage.Data());
625 //      cdbm->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
626
627   // HUGO: add to comment out the specific settings below in order to be able to run.
628   //cdbm->SetSpecificStorage("GRP/GRP/Data",fDefaultStorage.Data());
629         //cdbm->SetSpecificStorage("GRP/Geometry/data",fDefaultStorage.Data());
630         //cdbm->SetSpecificStorage("MUON/Calib/MappingData",fDefaultStorage.Data());
631         cdbm->SetRun(fCurrentRunNumber);
632
633   if (!AliMUONCDB::LoadField()) { AliError("Problem field"); return;}
634
635   // set the magnetic field for track extrapolations
636   AliMUONTrackExtrap::SetField();
637
638   if (!AliMUONCDB::LoadMapping(kTRUE)) { AliError("Problem mapping"); return;}
639
640         // recover default storage full name (raw:// cannot be used to set specific storage)
641         TString defaultStorage(cdbm->GetDefaultStorage()->GetType());
642         if (defaultStorage == "alien") defaultStorage += Form("://folder=%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
643         else defaultStorage += Form("://%s", cdbm->GetDefaultStorage()->GetBaseFolder().Data());
644
645         // reset existing geometry/alignment if any
646         if (cdbm->GetEntryCache()->Contains("GRP/Geometry/Data")) cdbm->UnloadFromCache("GRP/Geometry/Data");
647         if (cdbm->GetEntryCache()->Contains("MUON/Align/Data")) cdbm->UnloadFromCache("MUON/Align/Data");
648         if (AliGeomManager::GetGeometry()) AliGeomManager::GetGeometry()->UnlockGeometry();
649
650         // get original geometry transformer
651         AliGeomManager::LoadGeometry();
652         if (!AliGeomManager::GetGeometry()) { AliError("Problem geometry"); return;}
653         if (fOldAlignStorage != "none")
654   {
655
656                 if (!fOldAlignStorage.IsNull()) cdbm->SetSpecificStorage("MUON/Align/Data",fOldAlignStorage.Data());
657                 else cdbm->SetSpecificStorage("MUON/Align/Data",defaultStorage.Data());
658                 //              else cdbm->SetSpecificStorage("MUON/Align/Data",fDefaultStorage.Data());
659                 
660     AliGeomManager::ApplyAlignObjsFromCDB("MUON");
661
662   }
663
664   // fOldGeoTransformer = new AliMUONGeometryTransformer();
665         fOldGeoTransformer->LoadGeometryData();
666         fAlign->SetGeometryTransformer(fOldGeoTransformer);
667
668         fOCDBLoaded = kTRUE;
669
670 }