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