Use Alignable volume names
[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 "AliLog.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 <AliAlignObjAngles.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
60 //====================================================================
61 ClassImp(AliFMDAlignFaker)
62 #if 0
63   ; // This is here to keep Emacs for indenting the next line
64 #endif
65
66 //____________________________________________________________________
67 AliFMDAlignFaker::AliFMDAlignFaker(Int_t mask, const char* geo, 
68                                    const char* loc) 
69   : TTask(geo, loc),
70     fMask(mask),
71     fSensorTransMin(0,0,0),
72     fSensorTransMax(0,0,0),
73     fSensorRotMin(0,0,0),
74     fSensorRotMax(0,0,0),
75     fHalfTransMin(0,0,0),
76     fHalfTransMax(0,0,0),
77     fHalfRotMin(0,0,0),
78     fHalfRotMax(0,0,0),
79     fRunMin(0),
80     fRunMax(9999999), 
81     fArray(0),
82     fComment("")
83 {
84   // Default constructor 
85   if (!loc) { 
86     AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
87     if (!storage) AliFatal("Default Storage not set");
88     const TString& uri = storage->GetURI();
89     fTitle = uri;
90   }
91   SetSensorDisplacement();
92   SetSensorRotation();
93   SetHalfDisplacement();
94   SetHalfRotation();
95   SetComment();
96 }
97
98 //__________________________________________________________________
99 void
100 AliFMDAlignFaker::SetSensorDisplacement(Double_t x1, Double_t y1, Double_t z1,
101                                         Double_t x2, Double_t y2, Double_t z2)
102 {
103   // Set sensor displacement (unit is centimeters)
104   fSensorTransMin.SetXYZ(x1, y1, z1);
105   fSensorTransMax.SetXYZ(x2, y2, z2);
106 }
107
108 //__________________________________________________________________
109 void
110 AliFMDAlignFaker::SetSensorRotation(Double_t x1, Double_t y1, Double_t z1,
111                                     Double_t x2, Double_t y2, Double_t z2)
112 {
113   // Set sensor rotations (unit is degrees)
114   fSensorRotMin.SetXYZ(x1, y1, z1);
115   fSensorRotMax.SetXYZ(x2, y2, z2);
116 }
117
118 //__________________________________________________________________
119 void
120 AliFMDAlignFaker::SetHalfDisplacement(Double_t x1, Double_t y1, Double_t z1,
121                                       Double_t x2, Double_t y2, Double_t z2)
122 {
123   // Set half ring/cone displacement (unit is centimeters)
124   fHalfTransMin.SetXYZ(x1, y1, z1);
125   fHalfTransMax.SetXYZ(x2, y2, z2);
126 }
127
128 //__________________________________________________________________
129 void
130 AliFMDAlignFaker::SetHalfRotation(Double_t x1, Double_t y1, Double_t z1,
131                                   Double_t x2, Double_t y2, Double_t z2)
132 {
133   // Set half ring/cone rotations (unit is degrees)
134   fHalfRotMin.SetXYZ(x1, y1, z1);
135   fHalfRotMax.SetXYZ(x2, y2, z2);
136 }
137
138 //__________________________________________________________________
139 #define IS_NODE_HALF(name) \
140   (name[0] == 'F' && name[2] == 'M' && (name[3] == 'T' || name[3] == 'B'))
141 #define IS_NODE_SENSOR(name) \
142   (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
143
144 //__________________________________________________________________
145 void
146 AliFMDAlignFaker::Exec(Option_t*)
147 {
148   // Make the objects. 
149
150   // Get geometry 
151   if (!gGeoManager) {
152     if (!TGeoManager::Import(GetName())) {
153       AliFatal(Form("Failed to import geometry from %s", GetName()));
154       return;
155     }
156   }
157   // Get top volume 
158   TGeoVolume* topVolume = gGeoManager->GetTopVolume();
159   if (!topVolume) {
160     AliFatal("No top-level volume defined");
161     return;
162   }
163   // Make container of transforms 
164   if (!fArray) fArray = new TClonesArray("AliAlignObjAngles");
165   fArray->Clear();
166   
167   // Make an iterator
168   TGeoIterator next(topVolume);
169   next.SetTopName(Form("/%s_1", topVolume->GetName()));
170   TGeoNode* node = 0;
171   
172   Char_t currentDet  = '\0';
173   Char_t currentHalf = '\0';
174   // Loop over all entries in geometry to find our nodes. 
175   while ((node = static_cast<TGeoNode*>(next()))) {
176     const char* name =  node->GetName();
177     if (!(IS_NODE_HALF(name) && TESTBIT(fMask, kHalves)) &&
178         !(IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors))) 
179       continue;
180
181     TString path, alignName;
182     next.GetPath(path);
183     Int_t id = node->GetVolume()->GetNumber();
184     if (IS_NODE_HALF(name))   { 
185       currentDet    = name[1];
186       currentHalf   = name[3];
187       alignName     = Form("FMD/FMD%c_%c", currentDet, currentHalf);
188     }
189     if (IS_NODE_SENSOR(name)) {
190       Char_t ring  = name[1];
191       Int_t  copy  = node->GetNumber();
192       alignName    = Form("FMD/FMD%c_%c/FMD%c_%02d", 
193                           currentDet, currentHalf, ring, copy);
194     }
195     if (alignName.IsNull()) continue;
196     if (!gGeoManager->GetAlignableEntry(alignName.Data())) {
197       AliWarning(Form("No alignable entry for %s, using path %s",
198                       alignName.Data(), path.Data()));
199       alignName = path;
200     }
201     AliDebug(1, Form("Making alignment for %s -> %s (%d)", 
202                      alignName.Data(), path.Data(), id));
203     if (IS_NODE_HALF(name))   MakeAlignHalf(alignName, id);
204     if (IS_NODE_SENSOR(name)) MakeAlignSensor(alignName, id);
205 #if 0    
206     if (!(IS_NODE_HALF(name) && TESTBIT(fMask, kHalves)) &&
207         !(IS_NODE_SENSOR(name) && TESTBIT(fMask, kSensors))) 
208       continue;
209
210     // Get the path 
211     TString path(Form("/%s", gGeoManager->GetNode(0)->GetName()));
212     Int_t nLevel = next.GetLevel();
213     for (Int_t lvl = 0; lvl <= nLevel; lvl++) {
214       TGeoNode* p = next.GetNode(lvl);
215       if (!p) {
216         if (lvl != 0)
217           AliWarning(Form("No node at level %d in path %s",lvl,path.Data()));
218         continue;
219       }
220       if (!path.IsNull()) path.Append("/");
221       path.Append(p->GetName());
222     }
223     Int_t id = node->GetVolume()->GetNumber();
224     if (IS_NODE_HALF(name))   MakeAlignHalf(path, id);
225     if (IS_NODE_SENSOR(name)) MakeAlignSensor(path, id);
226 #endif 
227   }
228
229   TString t(GetTitle());
230   if (t.IsNull() || t.Contains("local://") || t.Contains("alien://")) 
231     WriteToCDB();
232   else 
233     WriteToFile();
234 }
235   
236 //__________________________________________________________________
237 Bool_t
238 AliFMDAlignFaker::MakeAlign(const TString& path, Int_t id, 
239                             Double_t transX, Double_t transY, Double_t transZ,
240                             Double_t rotX,   Double_t rotY, Double_t rotZ)
241 {
242   // make alignment for a path 
243   // Params: 
244   //   path      Path to node 
245   //   id        Volume number 
246   //   transX    Translation in X
247   //   transZ    Translation in Y
248   //   transZ    Translation in Z
249   //   rotX      Rotation about X-axis 
250   //   rotY      Rotation about Y-axis
251   //   rotZ      Rotation about Z-axis 
252   AliDebug(3, Form("Make alignment for %s (volume %d): (%f,%f,%f) (%f,%f,%f)", 
253                    path.Data(), id, transX, transY, transZ, rotX, rotY, rotZ));
254   Int_t nAlign = fArray->GetEntries();
255   id = 0;
256   AliAlignObjAngles* obj = 
257     new ((*fArray)[nAlign]) AliAlignObjAngles(path.Data(),
258                                               id,0,0,0,0,0,0,kTRUE);
259   if (!obj) {
260     AliError(Form("Failed to create alignment object for %s", path.Data()));
261     return kFALSE;
262   }
263   if (!obj->SetLocalPars(transX, transY, transZ, rotX, rotY, rotZ)) {
264     AliError(Form("Failed to set local transforms on %s", path.Data()));
265     return kTRUE;
266   }
267   return kTRUE;
268 }
269
270 //__________________________________________________________________
271 Bool_t
272 AliFMDAlignFaker::MakeAlignHalf(const TString& path, Int_t id)
273 {
274   // Make alignment of a half ring/cone 
275   AliDebug(15, Form("Make alignment for half-ring/cone %s", path.Data()));
276   Double_t transX = gRandom->Uniform(fHalfTransMin.X(), fHalfTransMax.X());
277   Double_t transY = gRandom->Uniform(fHalfTransMin.Y(), fHalfTransMax.Y());
278   Double_t transZ = gRandom->Uniform(fHalfTransMin.Z(), fHalfTransMax.Z());
279   Double_t rotX   = gRandom->Uniform(fHalfRotMin.X(),   fHalfRotMax.X());
280   Double_t rotY   = gRandom->Uniform(fHalfRotMin.Y(),   fHalfRotMax.Y());
281   Double_t rotZ   = gRandom->Uniform(fHalfRotMin.Z(),   fHalfRotMax.Z());
282   return MakeAlign(path, id, transX, transY, transZ, rotX, rotY, rotZ);
283 }
284
285   
286 //__________________________________________________________________
287 Bool_t
288 AliFMDAlignFaker::MakeAlignSensor(const TString& path, Int_t id)
289 {
290   // Make alignment of a sensor 
291   AliDebug(15, Form("Make alignment for sensor %s", path.Data()));
292   Double_t transX = gRandom->Uniform(fSensorTransMin.X(), fSensorTransMax.X());
293   Double_t transY = gRandom->Uniform(fSensorTransMin.Y(), fSensorTransMax.Y());
294   Double_t transZ = gRandom->Uniform(fSensorTransMin.Z(), fSensorTransMax.Z());
295   Double_t rotX   = gRandom->Uniform(fSensorRotMin.X(),   fSensorRotMax.X());
296   Double_t rotY   = gRandom->Uniform(fSensorRotMin.Y(),   fSensorRotMax.Y());
297   Double_t rotZ   = gRandom->Uniform(fSensorRotMin.Z(),   fSensorRotMax.Z());
298   return MakeAlign(path, id, transX, transY, transZ, rotX, rotY, rotZ);
299 }
300
301 //__________________________________________________________________
302 void
303 AliFMDAlignFaker::WriteToCDB()
304 {
305   // Make the objects. 
306   const char* loc = GetTitle();
307   AliCDBManager*     cdb  = AliCDBManager::Instance();
308   AliCDBStorage*  storage = cdb->GetStorage(!loc ? "" : loc);
309   AliCDBMetaData*    meta = new AliCDBMetaData; 
310   meta->SetResponsible(gSystem->GetUserInfo()->fRealName.Data()); 
311   meta->SetAliRootVersion(gROOT->GetVersion()); 
312   meta->SetBeamPeriod(1); 
313   meta->SetComment(fComment.Data());
314
315   AliCDBId id("FMD/Align/Data", fRunMin, fRunMax);
316   storage->Put(fArray, id, meta);
317 }
318
319 //__________________________________________________________________
320 void
321 AliFMDAlignFaker::WriteToFile()
322 {
323   // Write to a local file 
324   TFile* file = TFile::Open(GetTitle(), "RECREATE");
325   if (!file) {
326     AliFatal(Form("Failed to open file '%s' for output", GetTitle()));
327     return;
328   }
329   file->cd();
330   fArray->Write("FMDAlignment");
331   file->Write();
332   file->Close();
333 }
334
335   
336   
337 //____________________________________________________________________
338 //
339 // EOF
340 //