Moving the FMD offline trigger to its own class, AliFMDOfflineTrigger
[u/mrichter/AliRoot.git] / FMD / AliFMDAlignFaker.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 /* $Id$ */
16 /** @file    AliFMDAlignFaker.cxx
17     @author  Christian Holm Christensen <cholm@nbi.dk>
18     @date    Sun Mar 26 17:57:55 2006
19     @brief   Implementation of AliFMDAlignFaker 
20 */
21 //____________________________________________________________________
22 //
23 //  Class 
24 //  to 
25 //  make 
26 //  fake 
27 //  alignment
28 //  parameters 
29 //
30 //____________________________________________________________________
31 //                                                                          
32 // Forward Multiplicity Detector based on Silicon wafers. 
33 //
34 // This task creates fake alignment. Which alignment, depends on
35 // the bit mask passed to the constructor, or added by `AddAlign'.
36 //
37 // The default is to write all alignment parameters to a local
38 // storage `local://cdb' which is a directory in the current
39 // directory. 
40 //                                                       
41 #include "AliFMDDebug.h"                // ALIFMDDEBUG_H ALILOG_H
42 #include "AliFMDAlignFaker.h"      // ALIFMDALIGNFAKER_H
43 #include <AliCDBManager.h>         // ALICDBMANAGER_H
44 #include <AliCDBStorage.h>         // ALICDBSTORAGE_H
45 #include <AliCDBEntry.h>           // ALICDBMANAGER_H
46 // #include <AliAlignObj.h>
47 #include <AliAlignObjParams.h>
48 // #include <Riostream.h>
49 #include <TSystem.h>
50 // #include <TMath.h>
51 #include <TRandom.h>
52 #include <TClonesArray.h>
53 #include <TString.h>
54 #include <TFile.h>
55 #include <TGeoManager.h>
56 #include <TGeoNode.h>
57 // #include <TGeoVolume.h>
58 #include <TROOT.h>
59 #include <TClass.h>
60
61 //====================================================================
62 ClassImp(AliFMDAlignFaker)
63 #if 0
64   ; // This is here to keep Emacs for indenting the next line
65 #endif
66
67 //____________________________________________________________________
68 AliFMDAlignFaker::AliFMDAlignFaker(Int_t mask, const char* geo, 
69                                    const char* loc) 
70   : TTask(geo, loc),
71     fMask(mask),
72     fSensorTransMin(0,0,0),
73     fSensorTransMax(0,0,0),
74     fSensorRotMin(0,0,0),
75     fSensorRotMax(0,0,0),
76     fHalfTransMin(0,0,0),
77     fHalfTransMax(0,0,0),
78     fHalfRotMin(0,0,0),
79     fHalfRotMax(0,0,0),
80     fRunMin(0),
81     fRunMax(AliCDBRunRange::Infinity()), 
82     fArray(0),
83     fComment("")
84 {
85   // Default constructor 
86   if (!loc) { 
87     AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
88     if (!storage) AliFatal("Default Storage not set");
89     const TString& uri = storage->GetURI();
90     fTitle = uri;
91   }
92   SetSensorDisplacement();
93   SetSensorRotation();
94   SetHalfDisplacement();
95   SetHalfRotation();
96   SetComment();
97 }
98
99 //__________________________________________________________________
100 void
101 AliFMDAlignFaker::SetSensorDisplacement(Double_t x1, Double_t y1, Double_t z1,
102                                         Double_t x2, Double_t y2, Double_t z2)
103 {
104   // Set sensor displacement (unit is centimeters)
105   fSensorTransMin.SetXYZ(x1, y1, z1);
106   fSensorTransMax.SetXYZ(x2, y2, z2);
107 }
108
109 //__________________________________________________________________
110 void
111 AliFMDAlignFaker::SetSensorRotation(Double_t x1, Double_t y1, Double_t z1,
112                                     Double_t x2, Double_t y2, Double_t z2)
113 {
114   // Set sensor rotations (unit is degrees)
115   fSensorRotMin.SetXYZ(x1, y1, z1);
116   fSensorRotMax.SetXYZ(x2, y2, z2);
117 }
118
119 //__________________________________________________________________
120 void
121 AliFMDAlignFaker::SetHalfDisplacement(Double_t x1, Double_t y1, Double_t z1,
122                                       Double_t x2, Double_t y2, Double_t z2)
123 {
124   // Set half ring/cone displacement (unit is centimeters)
125   fHalfTransMin.SetXYZ(x1, y1, z1);
126   fHalfTransMax.SetXYZ(x2, y2, z2);
127 }
128
129 //__________________________________________________________________
130 void
131 AliFMDAlignFaker::SetHalfRotation(Double_t x1, Double_t y1, Double_t z1,
132                                   Double_t x2, Double_t y2, Double_t z2)
133 {
134   // Set half ring/cone rotations (unit is degrees)
135   fHalfRotMin.SetXYZ(x1, y1, z1);
136   fHalfRotMax.SetXYZ(x2, y2, z2);
137 }
138
139 //__________________________________________________________________
140 #define IS_NODE_HALF(name) \
141   (name[0] == 'F' && name[2] == 'M' && (name[3] == 'T' || name[3] == 'B'))
142 #define IS_NODE_SENSOR(name) \
143   (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
144
145 //__________________________________________________________________
146 Bool_t
147 AliFMDAlignFaker::GetGeometry(Bool_t toCdb, const TString& storage)
148 {
149   if (!toCdb) { 
150      //load geom from default CDB storage
151     AliGeomManager::LoadGeometry(); 
152     return kTRUE;
153   }
154   if(!storage.BeginsWith("local://") && 
155      !storage.BeginsWith("alien://")) {
156     AliErrorClass(Form("STORAGE=\"%s\" invalid. Exiting\n", storage.Data()));
157     return kFALSE;
158   }
159
160   AliCDBManager* cdb   = AliCDBManager::Instance();
161   AliCDBStorage* store = cdb->GetStorage(storage.Data());
162   if(!store){
163     AliErrorClass(Form("Unable to open storage %s\n", storage.Data()));
164     return kFALSE;
165   }
166
167   AliCDBPath   path("GRP","Geometry","Data");
168   AliCDBEntry* entry = store->Get(path.GetPath(),cdb->GetRun());
169   if(!entry) {
170     AliErrorClass("Could not get the specified CDB entry!");
171     return kFALSE;
172   }
173   
174
175   entry->SetOwner(0);
176   TGeoManager* geom = static_cast<TGeoManager*>(entry->GetObject());
177   AliGeomManager::SetGeometry(geom);
178   return kTRUE;
179 }
180   
181 //__________________________________________________________________
182 void
183 AliFMDAlignFaker::Exec(Option_t*)
184 {
185   // Make the objects. 
186
187   // Get geometry 
188   if (!gGeoManager) {
189     if (!TGeoManager::Import(GetName())) {
190       AliFatal(Form("Failed to import geometry from %s", GetName()));
191       return;
192     }
193   }
194   // Get top volume 
195   TGeoVolume* topVolume = gGeoManager->GetTopVolume();
196   if (!topVolume) {
197     AliFatal("No top-level volume defined");
198     return;
199   }
200   // Make container of transforms 
201   if (!fArray) fArray = new TClonesArray("AliAlignObjParams");
202   fArray->Clear();
203   
204   // Make an iterator
205   TGeoIterator next(topVolume);
206   next.SetTopName(Form("/%s_1", topVolume->GetName()));
207   TGeoNode* node = 0;
208   
209   Char_t currentDet  = '\0';
210   Char_t currentHalf = '\0';
211   // Loop over all entries in geometry to find our nodes. 
212   while ((node = static_cast<TGeoNode*>(next()))) {
213     const char* name =  node->GetName();
214     if (!(IS_NODE_HALF(name) && TESTBIT(fMask, kHalves)) &&
215         !(IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors))) 
216       continue;
217
218     TString path, alignName;
219     next.GetPath(path);
220     Int_t id = node->GetVolume()->GetNumber();
221     if (IS_NODE_HALF(name))   { 
222       currentDet    = name[1];
223       currentHalf   = name[3];
224       alignName     = Form("FMD/FMD%c_%c", currentDet, currentHalf);
225     }
226     if (IS_NODE_SENSOR(name)) {
227       Char_t ring      = name[1];
228       Int_t  lvl       = next.GetLevel();
229       TGeoNode* parent = next.GetNode(lvl-1);
230       Int_t     copy   = parent->GetNumber();
231       alignName        = Form("FMD/FMD%c_%c/FMD%c_%02d", 
232                           currentDet, currentHalf, ring, copy);
233     }
234     if (alignName.IsNull()) continue;
235     if (!gGeoManager->GetAlignableEntry(alignName.Data())) {
236       AliWarning(Form("No alignable entry for %s, using path %s",
237                       alignName.Data(), path.Data()));
238       alignName = path;
239     }
240     AliFMDDebug(1, ("Making alignment for %s -> %s (%d)", 
241                      alignName.Data(), path.Data(), id));
242     if (IS_NODE_HALF(name))   MakeAlignHalf(alignName, id);
243     if (IS_NODE_SENSOR(name)) MakeAlignSensor(alignName, id);
244 #if 0    
245     if (!(IS_NODE_HALF(name) && TESTBIT(fMask, kHalves)) &&
246         !(IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors))) 
247       continue;
248
249     // Get the path 
250     TString path(Form("/%s", gGeoManager->GetNode(0)->GetName()));
251     Int_t nLevel = next.GetLevel();
252     for (Int_t lvl = 0; lvl <= nLevel; lvl++) {
253       TGeoNode* p = next.GetNode(lvl);
254       if (!p) {
255         if (lvl != 0)
256           AliWarning(Form("No node at level %d in path %s",lvl,path.Data()));
257         continue;
258       }
259       if (!path.IsNull()) path.Append("/");
260       path.Append(p->GetName());
261     }
262     Int_t id = node->GetVolume()->GetNumber();
263     if (IS_NODE_HALF(name))   MakeAlignHalf(path, id);
264     if (IS_NODE_SENSOR(name)) MakeAlignSensor(path, id);
265 #endif 
266   }
267
268   TString t(GetTitle());
269   if (t.IsNull() || t.Contains("local://") || t.Contains("alien://")) 
270     WriteToCDB();
271   else 
272     WriteToFile();
273 }
274   
275 //__________________________________________________________________
276 Bool_t
277 AliFMDAlignFaker::MakeAlign(const TString& path, Int_t id, 
278                             Double_t transX, Double_t transY, Double_t transZ,
279                             Double_t rotX,   Double_t rotY, Double_t rotZ)
280 {
281   // make alignment for a path 
282   // Params: 
283   //   path      Path to node 
284   //   id        Volume number 
285   //   transX    Translation in X
286   //   transZ    Translation in Y
287   //   transZ    Translation in Z
288   //   rotX      Rotation about X-axis 
289   //   rotY      Rotation about Y-axis
290   //   rotZ      Rotation about Z-axis 
291   AliFMDDebug(3, ("Make alignment for %s (volume %d): (%f,%f,%f) (%f,%f,%f)", 
292                    path.Data(), id, transX, transY, transZ, rotX, rotY, rotZ));
293   Int_t nAlign = fArray->GetEntries();
294   id = 0;
295   AliAlignObjParams* obj = 
296     new ((*fArray)[nAlign]) AliAlignObjParams(path.Data(),
297                                               id,0,0,0,0,0,0,kTRUE);
298   if (!obj) {
299     AliError(Form("Failed to create alignment object for %s", path.Data()));
300     return kFALSE;
301   }
302   if (!obj->SetLocalPars(transX, transY, transZ, rotX, rotY, rotZ)) {
303     AliError(Form("Failed to set local transforms on %s", path.Data()));
304     return kTRUE;
305   }
306   return kTRUE;
307 }
308
309 //__________________________________________________________________
310 Bool_t
311 AliFMDAlignFaker::MakeAlignHalf(const TString& path, Int_t id)
312 {
313   // Make alignment of a half ring/cone 
314   AliFMDDebug(15, ("Make alignment for half-ring/cone %s", path.Data()));
315   Double_t transX = gRandom->Uniform(fHalfTransMin.X(), fHalfTransMax.X());
316   Double_t transY = gRandom->Uniform(fHalfTransMin.Y(), fHalfTransMax.Y());
317   Double_t transZ = gRandom->Uniform(fHalfTransMin.Z(), fHalfTransMax.Z());
318   Double_t rotX   = gRandom->Uniform(fHalfRotMin.X(),   fHalfRotMax.X());
319   Double_t rotY   = gRandom->Uniform(fHalfRotMin.Y(),   fHalfRotMax.Y());
320   Double_t rotZ   = gRandom->Uniform(fHalfRotMin.Z(),   fHalfRotMax.Z());
321   return MakeAlign(path, id, transX, transY, transZ, rotX, rotY, rotZ);
322 }
323
324   
325 //__________________________________________________________________
326 Bool_t
327 AliFMDAlignFaker::MakeAlignSensor(const TString& path, Int_t id)
328 {
329   // Make alignment of a sensor 
330   AliFMDDebug(15, ("Make alignment for sensor %s", path.Data()));
331   Double_t transX = gRandom->Uniform(fSensorTransMin.X(), fSensorTransMax.X());
332   Double_t transY = gRandom->Uniform(fSensorTransMin.Y(), fSensorTransMax.Y());
333   Double_t transZ = gRandom->Uniform(fSensorTransMin.Z(), fSensorTransMax.Z());
334   Double_t rotX   = gRandom->Uniform(fSensorRotMin.X(),   fSensorRotMax.X());
335   Double_t rotY   = gRandom->Uniform(fSensorRotMin.Y(),   fSensorRotMax.Y());
336   Double_t rotZ   = gRandom->Uniform(fSensorRotMin.Z(),   fSensorRotMax.Z());
337   return MakeAlign(path, id, transX, transY, transZ, rotX, rotY, rotZ);
338 }
339
340 //__________________________________________________________________
341 void
342 AliFMDAlignFaker::WriteToCDB()
343 {
344   // Make the objects. 
345   const char* loc = GetTitle();
346   AliCDBManager*     cdb  = AliCDBManager::Instance();
347   AliCDBStorage*  storage = cdb->GetStorage(!loc ? "" : loc);
348   AliCDBMetaData*    meta = new AliCDBMetaData; 
349   meta->SetResponsible(gSystem->GetUserInfo()->fRealName.Data()); 
350   meta->SetAliRootVersion(gROOT->GetVersion()); 
351   meta->SetBeamPeriod(1); 
352   meta->SetComment(fComment.Data());
353
354   AliCDBId id("FMD/Align/Data", fRunMin, fRunMax);
355   storage->Put(fArray, id, meta);
356 }
357
358 //__________________________________________________________________
359 void
360 AliFMDAlignFaker::WriteToFile()
361 {
362   // Write to a local file 
363   TFile* file = TFile::Open(GetTitle(), "RECREATE");
364   if (!file) {
365     AliFatal(Form("Failed to open file '%s' for output", GetTitle()));
366     return;
367   }
368   file->cd();
369   fArray->Write("FMDAlignment",TObject::kSingleKey);
370   file->Write();
371   file->Close();
372 }
373
374   
375   
376 //____________________________________________________________________
377 //
378 // EOF
379 //