20-apr-2005 NvE Id of owning device added to the output of AliSignal::Data().
authornick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 21 Apr 2005 14:11:08 +0000 (14:11 +0000)
committernick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 21 Apr 2005 14:11:08 +0000 (14:11 +0000)
21-apr-2005 NvE Directory iceconvert introduced to hold the various readers to
                convert Amanda/IceCube data into the Ralice/IcePack event structures.

43 files changed:
RALICE/AliSignal.cxx
RALICE/history.txt
RALICE/icepack/history.txt
RALICE/icepack/iceconvert/ICEConvHeaders.h [new file with mode: 0644]
RALICE/icepack/iceconvert/ICEConvLinkDef.h [new file with mode: 0644]
RALICE/icepack/iceconvert/IceF2k.cxx [new file with mode: 0644]
RALICE/icepack/iceconvert/IceF2k.h [new file with mode: 0644]
RALICE/icepack/iceconvert/amanda.c [new file with mode: 0644]
RALICE/icepack/iceconvert/amanda.h [new file with mode: 0644]
RALICE/icepack/iceconvert/baikal.c [new file with mode: 0644]
RALICE/icepack/iceconvert/baikal.h [new file with mode: 0644]
RALICE/icepack/iceconvert/dumand.c [new file with mode: 0644]
RALICE/icepack/iceconvert/dumand.h [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k.h [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_1x1.c [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_1x2.c [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_1x3.c [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_1x4.c [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_2004x1.c [new file with mode: 0644]
RALICE/icepack/iceconvert/f2k_utl.c [new file with mode: 0644]
RALICE/icepack/iceconvert/history.txt [new file with mode: 0644]
RALICE/icepack/iceconvert/macros/icef2k.cc [new file with mode: 0644]
RALICE/icepack/iceconvert/macros/open.cc [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc.h [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_WF.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_array.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_array_calib.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_hdef.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_jk.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_local.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_local.h [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mcfile.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mcopen.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mevt.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mevt_special.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mevt_uses.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mhit.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_mtrack.c [new file with mode: 0644]
RALICE/icepack/iceconvert/rdmc_time.c [new file with mode: 0644]
RALICE/icepack/iceconvert/scripts/mklibs.bat [new file with mode: 0755]
RALICE/icepack/iceconvert/uwi.c [new file with mode: 0644]
RALICE/icepack/iceconvert/uwi.h [new file with mode: 0644]

index 5caa22d6f15aae68a5b810f96d35b0e24b37d598..b1c9ac10b2465c0db172ae25a6bd1ce9d9bdf3ca 100644 (file)
@@ -560,7 +560,7 @@ void AliSignal::Data(TString f) const
  const char* name=GetName();
  const char* title=GetTitle();
 
- cout << " *" << ClassName() << "::Data* Id :" << GetUniqueID();
+ cout << " *" << ClassName() << "::Data* Id : " << GetUniqueID();
  if (strlen(name))  cout << " Name : " << name;
  if (strlen(title)) cout << " Title : " << title;
  cout << endl;
@@ -570,7 +570,8 @@ void AliSignal::Data(TString f) const
  {
   const char* devname=fDevice->GetName();
   const char* devtitle=fDevice->GetTitle();
-  cout << "   Owned by device : " << fDevice->ClassName();
+  cout << "   Owned by device : " << fDevice->ClassName()
+       << " Id : " << fDevice->GetUniqueID();
   if (strlen(devname))  cout << " Name : " << devname;
   if (strlen(devtitle)) cout << " Title : " << devtitle;
   cout << endl;
index 83c0fb61e23e281575580c74e47bddb0ff18a69c..71a608da1c739b326d672dd7fec02773bfa5d06a 100644 (file)
                 New memberfunction ShowTracks introduced in AliJet and memberfunction Data() updated.
 18-apr-2005 NvE New memberfunction GetTracks introduced in AliJet to provide various track selections.
 19-apr-2005 NvE Memberfunctions GetNtracks and GetTracks of AliJet extended in functionality.
+20-apr-2005 NvE Id of owning device added to the output of AliSignal::Data().
index e07bb82b700ce6a863d2cdeb989a1c60263d8920..1295630dbfe0aebd70ad68973c83f75fa5da5ecb 100644 (file)
@@ -5,3 +5,5 @@
 18-feb-2005 NvE Copyright format modified in all .cxx source files in line with Ralice
                 such that the text shows up correctly in the auto-generated html docs.
 13-apr-2005 NvE Documentation of IceEvent updated w.r.t. the labeling of MC and Reco tracks.
+21-apr-2005 NvE Directory iceconvert introduced to hold the various readers to
+                convert Amanda/IceCube data into the Ralice/IcePack event structures.
diff --git a/RALICE/icepack/iceconvert/ICEConvHeaders.h b/RALICE/icepack/iceconvert/ICEConvHeaders.h
new file mode 100644 (file)
index 0000000..6d21143
--- /dev/null
@@ -0,0 +1,12 @@
+///////////////////////////////////////////////////////////////////////////
+// All headers of the ICE format conversion software
+// This header list is used to create the ICE dictionary via rootcint.
+//
+// Note : Class names have also to be entered into the list
+//        contained in ICEConvLinkDef.h
+//
+//--- NvE 11-mar-2005 Utrecht University
+///////////////////////////////////////////////////////////////////////////
+#include "IceF2k.h"
+
diff --git a/RALICE/icepack/iceconvert/ICEConvLinkDef.h b/RALICE/icepack/iceconvert/ICEConvLinkDef.h
new file mode 100644 (file)
index 0000000..218a58f
--- /dev/null
@@ -0,0 +1,18 @@
+///////////////////////////////////////////////////////////////////////////
+// All classes of the ICE format conversion software
+// This class list is used to create the ICE dictionary via rootcint.
+//
+// Note : Headers have also to be entered into the list
+//        contained in ICEConvHeaders.h
+//
+//--- NvE 11-mar-2005 Utrecht University
+///////////////////////////////////////////////////////////////////////////
+#ifdef __CINT__
+ #pragma link off all globals;
+ #pragma link off all classes;
+ #pragma link off all functions;
+ #pragma link C++ class IceF2k+;
+#endif
diff --git a/RALICE/icepack/iceconvert/IceF2k.cxx b/RALICE/icepack/iceconvert/IceF2k.cxx
new file mode 100644 (file)
index 0000000..b578c0e
--- /dev/null
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
+ *
+ * Author: The IceCube RALICE-based Offline Project.
+ * Contributors are mentioned in the code where appropriate.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation strictly for non-commercial purposes is hereby granted
+ * without fee, provided that the above copyright notice appears in all
+ * copies and that both the copyright notice and this permission notice
+ * appear in the supporting documentation.
+ * The authors make no claims about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *******************************************************************************/
+
+// $Id$
+
+///////////////////////////////////////////////////////////////////////////
+// Class IceF2k
+// Conversion of Amanda F2K data into IceEvent physics event structures.
+//
+// Usage example :
+// ---------------
+//
+// gSystem->Load("ralice");
+// gSystem->Load("icepack");
+// gSystem->Load("iceconvert");
+//
+// // Output file for the event structures
+// TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
+// TTree* otree=new TTree("T","Data of an Amanda run");
+//
+// // Limit the number of entries for testing
+// Int_t nentries=300;
+//
+// // Print frequency to produce a short summary print every printfreq events
+// Int_t printfreq=10;
+//
+// // Split level for the output structures
+// Int_t split=2;
+//
+// // Buffer size for the output structures
+// Int_t bsize=32000;
+//
+// IceF2k q("run8000.f2k",split,bsize);
+// q.Loop(otree,nentries,printfreq);
+//
+// // Select various objects to be added to the output file
+//
+// AliObjMatrix* omdb=q.GetOMdbase();
+// if (omdb) omdb->Write();
+//
+// AliDevice* fitdefs=q.GetFitdefs();
+// if (fitdefs) fitdefs->Write();
+//
+// TDatabasePDG* pdg=q.GetPDG();
+// if (pdg) pdg->Write();
+//
+// // Close output file
+// ofile->Write();
+// ofile->Close();
+//
+//--- Author: Nick van Eijndhoven 11-mar-2005 Utrecht University
+//- Modified: NvE $Date$ Utrecht University
+///////////////////////////////////////////////////////////////////////////
+#include "IceF2k.h"
+#include "Riostream.h"
+
+ClassImp(IceF2k) // Class implementation to enable ROOT I/O
+
+IceF2k::IceF2k(char* fname,Int_t split,Int_t bsize)
+{
+// Default constructor.
+// Initialise the input file and data structres to be converted.
+// Also the required split level and buffer size of the output tree
+// can be specified in this constructor.
+// By default tree=0, split=0 and bsize=32000.
+
+ fSplit=split;
+ fBsize=bsize;
+
+ fPdg=0;
+ fOmdb=0;
+ fFitdefs=0;
+
+ if (!fname)
+ {
+  cout << " *IceF2k ctor* No data input file specified." << endl;
+  return;
+ }
+
+ // Open the input file in the default ascii format (autodetection) for reading 
+ fInput=rdmc_mcopen(fname,"r",RDMC_DEFAULT_ASCII_F);
+
+ if (!fInput)
+ {
+  cout << " *IceF2k ctor* No input file found with name : " << fname << endl;
+  return;
+ }
+
+ // Initialise the event structure 
+ rdmc_init_mevt(&fEvent);
+
+ // Read the file header information
+ rdmc_rarr(fInput,&fHeader);
+}
+///////////////////////////////////////////////////////////////////////////
+IceF2k::~IceF2k()
+{
+// Default destructor.
+ if (fPdg)
+ {
+  delete fPdg;
+  fPdg=0;
+ }
+
+ if (fOmdb)
+ {
+  delete fOmdb;
+  fOmdb=0;
+ }
+
+ if (fFitdefs)
+ {
+  delete fFitdefs;
+  fFitdefs=0;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+TDatabasePDG* IceF2k::GetPDG()
+{
+// Provide pointer to the PDG database
+ return fPdg;
+}
+///////////////////////////////////////////////////////////////////////////
+AliObjMatrix* IceF2k::GetOMdbase()
+{
+// Provide pointer to the OM geometry, calib. etc... database
+ return fOmdb;
+}
+///////////////////////////////////////////////////////////////////////////
+AliDevice* IceF2k::GetFitdefs()
+{
+// Provide pointer to the fit definitions
+ return fFitdefs;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::Loop(TTree* otree,Int_t nentries,Int_t printfreq)
+{
+// Loop over the specified number of entries and convert the 
+// F2K data into the IceEvent structure.
+// The output will be written on the output tree specified as "otree".
+// If otree=0, a default standard output tree will be created.
+// If nentries<0 (default) all the entries of the input file
+// will be processed.
+// Every "printfreq" events a short event summary will be printed.
+// The default value is printfreq=1.
+
+ if (!fInput || fSplit<0) return;
+
+ if (!otree) otree=new TTree("T","F2K Data");
+
+ Double_t pi=acos(-1.);
+
+ IceEvent* evt=new IceEvent();
+
+ evt->SetTrackCopy(1);
+ evt->SetDevCopy(1);
+
+ // Branch in the tree for the event structure
+ otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit); 
+
+ // Create the particle database and extend it with some F2000 specific definitions
+ if (!fPdg) fPdg=new TDatabasePDG();
+ Double_t me=fPdg->GetParticle(11)->Mass();
+ fPdg->AddParticle("brems"   ,"brems"   ,0,1,0,0,"none",10001001,0,0);
+ fPdg->AddParticle("deltae"  ,"deltae"  ,me,1,0,-3,"Lepton",10001002,0,0);
+ fPdg->AddParticle("pairprod","pairprod",0,1,0,0,"none",10001003,0,0);
+ fPdg->AddParticle("nucl_int","nucl_Int",0,1,0,0,"none",10001004,0,0);
+ fPdg->AddParticle("mu_pair" ,"mu_pair" ,0,1,0,0,"none",10001005,0,0);
+ fPdg->AddParticle("hadrons" ,"hadrons" ,0,1,0,0,"none",10001006,0,0);
+ fPdg->AddParticle("fiberlaser","fiberlaser",0,1,0,0,"none",10002100,0,0);
+ fPdg->AddParticle("n2laser"   ,"n2laser"   ,0,1,0,0,"none",10002101,0,0);
+ fPdg->AddParticle("yaglaser"  ,"yaglaser"  ,0,1,0,0,"none",10002201,0,0);
+ fPdg->AddParticle("z_primary","z_primary",0,1,0,0,"none",10003000,0,0);
+ fPdg->AddParticle("a_primary","a_primary",0,1,0,0,"none",10003500,0,0);
+
+ // Fill the database with geometry, calib. etc... parameters
+ // for all the devices
+ FillOMdbase();
+
+ // Set the fit definitions according to the F2000 header info
+ SetFitdefs();
+
+/*************
+
+ // The LEDA specific output data
+ AliCalorimeter* ledaup=new AliCalorimeter(44,144);
+ AliCalorimeter* ledalw=new AliCalorimeter(40,144);
+
+ ledaup->SetName("LedaUp");
+ ledalw->SetName("LedaDown");
+
+ evt->InitLeda(ledaup);
+ evt->InitLeda(ledalw);
+
+ TDatime datim;
+ Float_t pos[3],costh;
+ AliSignal s;
+ s.SetName("CPV signal ADC");
+************************/
+
+ for (Int_t jentry=0; jentry<nentries; jentry++)
+ {
+  if (rdmc_revt(fInput,&fHeader,&fEvent) != 0) break;
+
+  // Reset the complete Event structure
+  evt->Reset();
+
+  evt->SetRunNumber(fEvent.nrun);
+  evt->SetEventNumber(fEvent.enr);
+  evt->SetMJD(fEvent.mjd,fEvent.secs,fEvent.nsecs);
+
+  PutMcTracks(evt);
+
+  PutRecoTracks(evt);
+
+  PutHits(evt);
+
+/*********************************
+  datim.Set(Jdate,Jtime);
+  evt->SetDayTime(datim);
+  evt->SetProjectile(207,82,158);
+  evt->SetTarget(207,82,0);
+  evt->SetWeight(Jwscal);
+  evt->SetTrig(Itword);
+  evt->SetZdc(Zdc*1000.);
+  evt->SetMiracE(1000.*Emir,Emire,Emirh);
+  evt->SetMiracEt(Etm,Etme,Etmh);
+  ledaup->Reset();
+  ledalw->Reset();
+  // Fill calorimeter with module data
+  for (Int_t i=0; i<Nmod; i++)
+  {
+   if (Adcl[i] > 3) // Adc cut of 3 to remove noise
+   {
+    if (Irowl[i] > 0) ledaup->SetSignal(Irowl[i],Icoll[i],Adcl[i]);
+    if (Irowl[i] < 0) ledalw->SetSignal(-Irowl[i],Icoll[i],Adcl[i]);
+   }
+  }
+
+  // Store associated CPV signals
+  for (Int_t j=0; j<Ncluv; j++)
+  {
+   s.Reset();
+   s.SetSignal(Iadccv[j]);
+   pos[1]=Thetacv[j]*pi/180.;
+   pos[2]=Phicv[j]*pi/180.;
+   costh=cos(pos[1]);
+   pos[0]=0;
+   if (costh) pos[0]=2103./costh;
+   s.SetPosition(pos,"sph");
+   pos[0]=0.4;
+   pos[1]=2.2;
+   pos[2]=0;
+   s.SetPositionErrors(pos,"car");
+   if (Phicv[j]>=0. && Phicv[j]<=180.)
+   {
+    ledaup->AddVetoSignal(s);
+   }
+   else
+   {
+    ledalw->AddVetoSignal(s);
+   }
+  }
+
+  evt->AddDevice(ledaup);
+  evt->AddDevice(ledalw);
+************************************/
+
+  if (!(jentry%printfreq))
+  {
+   evt->HeaderData();
+  }
+
+  // Write the complete structure to the output Tree
+  otree->Fill();
+ }
+
+ if (evt) delete evt;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::FillOMdbase()
+{
+// Fill the database with geometry, calib. etc... parameters 
+// for all the devices.
+
+ if (fHeader.nch<=0) return;
+
+ if (fOmdb)
+ {
+  fOmdb->Reset();
+ }
+ else
+ {
+  fOmdb=new AliObjMatrix();
+  fOmdb->SetNameTitle("OMDBASE","The OM geometry, calib. etc... database");
+  fOmdb->SetOwner();
+ }
+
+ IceAOM* dev=0;
+ Double_t pos[3]={0,0,0};
+ for (Int_t i=0; i<fHeader.nch; i++)
+ {
+  dev=new IceAOM();
+  dev->SetUniqueID(i+1);
+  dev->SetSlotName("TYPE",1);
+  dev->SetSlotName("ORIENT",2);
+  dev->SetSlotName("T0",3);
+  dev->SetSlotName("ALPHA",4);
+  dev->SetSlotName("KADC",5);
+  dev->SetSlotName("KTOT",6);
+  dev->SetSlotName("KTDC",7);
+
+  pos[0]=fHeader.x[i];
+  pos[1]=fHeader.y[i];
+  pos[2]=fHeader.z[i];
+  dev->SetPosition(pos,"car");
+  dev->SetSignal(fHeader.type[i],1);
+  dev->SetSignal((Float_t)fHeader.costh[i],2);
+  dev->SetSignal(fHeader.cal[i].t_0,3);
+  dev->SetSignal(fHeader.cal[i].alpha_t,4);
+  dev->SetSignal(fHeader.cal[i].beta_a,5);
+  dev->SetSignal(fHeader.cal[i].beta_tot,6);
+  dev->SetSignal(fHeader.cal[i].beta_t,7);
+  fOmdb->EnterObject(i+1,1,dev);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetFitdefs()
+{
+// Obtain the names of the variables for each fit procedure from the
+// f2000 header. Each different fit procedure is then stored as a separate
+// hit of an AliDevice object and the various fit variables are stored
+// as separate signal slots of the corresponding hit.
+// Via the GetFitdefs() memberfunction this AliDevice object can be
+// retrieved and stored in the ROOT output file if wanted.
+// The name of the object is FitDefinitions and the stored data can be
+// inspected via the AliDevice::Data() memberfunction and looks as follows :
+//
+//  *AliDevice::Data* Id :0 Name : FitDefinitions
+//    Position Vector in car coordinates : 0 0 0
+//    Err. in car coordinates : 0 0 0
+//  The following 8 hits are registered :
+//  *AliSignal::Data* Id :0
+//    Position Vector in car coordinates : 0 0 0
+//    Err. in car coordinates : 0 0 0
+//    Owned by device : AliDevice Name : FitDefinitions
+//    Slot : 1 Signal value : 1 name : id
+//    Slot : 2 Signal value : 2 name : rchi2
+//    Slot : 3 Signal value : 3 name : prob
+//    Slot : 4 Signal value : 4 name : sigth
+//    Slot : 5 Signal value : 5 name : covmin
+//    Slot : 6 Signal value : 6 name : covmax
+//    Slot : 7 Signal value : 7 name : cutflag
+//    Slot : 8 Signal value : 8 name : chi2
+//  *AliSignal::Data* Id :1
+//    Position Vector in car coordinates : 0 0 0
+//    Err. in car coordinates : 0 0 0
+//    Owned by device : AliDevice Name : FitDefinitions
+//    Slot : 1 Signal value : 1 name : id
+//    Slot : 2 Signal value : 2 name : rchi2
+//    Slot : 3 Signal value : 3 name : prob
+// etc....  
+//
+// This memberfunction is based on the original idea/code by Adam Bouchta.
+
+ if (fHeader.n_fit<=0) return;
+
+ if (fFitdefs)
+ {
+  fFitdefs->Reset(1);
+ }
+ else
+ {
+  fFitdefs=new AliDevice();
+ }
+
+ fFitdefs->SetName("FitDefinitions");
+ fFitdefs->SetHitCopy (1);
+
+ AliSignal s;
+ s.Reset();
+
+ for (Int_t i=0; i<fHeader.n_fit; i++)
+ {
+  s.SetUniqueID(fHeader.def_fit[i].id);
+
+  for (Int_t j=0; j<fHeader.def_fit[i].nwords; j++)
+  {
+   s.SetSlotName(TString(fHeader.def_fit[i].words[j]),j+1);
+   s.SetSignal(j+1,j+1);
+  }
+
+  fFitdefs->AddHit(s);
+  s.Reset(1);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::PutMcTracks(IceEvent* evt)
+{
+// Get the MC tracks from the F2000 file into the IcePack structure.
+// Note : MC tracks are given negative track id's in the event structure.
+// This memberfunction is based on the original code by Adam Bouchta.
+
+ if (!evt || fEvent.ntrack<=0) return;
+
+ // Loop over all the tracks and add them to the current event
+ AliTrack t;
+ Double_t vec[3];
+ AliPosition r;
+ Ali3Vector p;
+ Int_t tid=0;
+ Int_t idpdg=0;
+ Int_t idf2k=0;
+ for (Int_t i=0; i<fEvent.ntrack; i++)
+ {
+  t.Reset ();
+
+  // Beginpoint of the track
+  vec[0]=fEvent.gen[i].x;
+  vec[1]=fEvent.gen[i].y;
+  vec[2]=fEvent.gen[i].z;
+  r.SetPosition(vec,"car");
+  t.SetBeginPoint(r);
+
+  // Endpoint of the track
+  vec[0]+=fEvent.gen[i].length*fEvent.gen[i].px;
+  vec[1]+=fEvent.gen[i].length*fEvent.gen[i].py;
+  vec[2]+=fEvent.gen[i].length*fEvent.gen[i].pz;
+  r.SetPosition(vec,"car");
+  t.SetEndPoint(r);
+
+  // Momentum in GeV/c
+  vec[0]=fEvent.gen[i].e*fEvent.gen[i].px*1e-3;
+  vec[1]=fEvent.gen[i].e*fEvent.gen[i].py*1e-3;
+  vec[2]=fEvent.gen[i].e*fEvent.gen[i].pz*1e-3;
+  p.SetVector (vec,"car");
+  t.Set3Momentum(p);
+
+  // MC tracks are indicated by negative track id's
+  tid=fEvent.gen[i].tag;
+  t.SetId(-abs(tid));
+
+  idf2k=fEvent.gen[i].id;
+  idpdg=0;
+  if (idf2k>1000)
+  {
+   idpdg=idf2k+10000000;
+  }
+  else if (idf2k <= 48)
+  {
+   idpdg=fPdg->ConvertGeant3ToPdg(idf2k);
+  }
+  else
+  {
+   if (idf2k==201) idpdg=12;
+   if (idf2k==202) idpdg=14;
+   if (idf2k==203) idpdg=16;
+   if (idf2k==204) idpdg=-12;
+   if (idf2k==205) idpdg=-14;
+   if (idf2k==206) idpdg=-16;
+  }
+
+  t.SetParticleCode(idpdg);
+  t.SetName(fPdg->GetParticle(idpdg)->GetName());
+  t.SetTitle("MC track");
+  t.SetMass(fPdg->GetParticle(idpdg)->Mass());
+  t.SetCharge(fPdg->GetParticle(idpdg)->Charge()/3.);
+
+  evt->AddTrack(t);
+ }
+
+ // Create the pointers to each particle's parent particle.
+ Int_t txid=0;
+ Int_t parid=0;
+ for (Int_t itk=1; itk<=evt->GetNtracks (); itk++)
+ {
+  AliTrack* tx=evt->GetTrack(itk);
+
+  if (!tx) continue;
+
+  txid=tx->GetId();
+
+  parid=-1;
+  for (Int_t j=0; j<fEvent.ntrack; j++)
+  {
+   tid=fEvent.gen[j].tag;
+   if (-abs(tid) == txid) parid=fEvent.gen[j].parent;
+  }
+
+  if (parid<0) continue;
+
+  AliTrack* tpar=evt->GetIdTrack(-abs(parid));
+
+  if (!tpar) continue;
+
+  tx->SetParentTrack(tpar);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::PutRecoTracks(IceEvent* evt)
+{
+// Get the reconstructed tracks from the F2000 file into the IcePack structure.
+// Note : Reco tracks are given positive track id's in the event structure.
+// This memberfunction is based on the original code by Adam Bouchta.
+
+ if (!evt || fEvent.nfit<=0) return;
+
+ // Loop over all the tracks and add them to the current event
+ AliTrack t;
+ Double_t vec[3];
+ AliPosition r;
+ Ali3Vector p;
+ Int_t tid=0;
+ Int_t idpdg=0;
+ Int_t idf2k=0;
+ for (Int_t i=0; i<fEvent.nfit; i++)
+ {
+  t.Reset ();
+
+  // Beginpoint of the track
+  vec[0]=fEvent.rec[i].x;
+  vec[1]=fEvent.rec[i].y;
+  vec[2]=fEvent.rec[i].z;
+  r.SetPosition(vec,"car");
+  t.SetBeginPoint(r);
+
+  // Endpoint of the track
+  vec[0]+=fEvent.rec[i].length*fEvent.rec[i].px;
+  vec[1]+=fEvent.rec[i].length*fEvent.rec[i].py;
+  vec[2]+=fEvent.rec[i].length*fEvent.rec[i].pz;
+  r.SetPosition(vec,"car");
+  t.SetEndPoint(r);
+
+  // Momentum in GeV/c
+  if (fEvent.rec[i].e > 0)
+  {
+   vec[0]=fEvent.rec[i].e*fEvent.rec[i].px*1e-3;
+   vec[1]=fEvent.rec[i].e*fEvent.rec[i].py*1e-3;
+   vec[2]=fEvent.rec[i].e*fEvent.rec[i].pz*1e-3;
+  }
+  else // Give the track a nominal momentum of 1 GeV/c
+  {
+   vec[0]=fEvent.rec[i].px;
+   vec[1]=fEvent.rec[i].py;
+   vec[2]=fEvent.rec[i].pz;
+  }
+  p.SetVector (vec,"car");
+  t.Set3Momentum(p);
+
+  // Use the fit number as track id
+  tid=fEvent.rec[i].tag;
+  t.SetId(abs(tid));
+
+  idf2k=fEvent.rec[i].id;
+  idpdg=0;
+  if (idf2k>1000)
+  {
+   idpdg=idf2k+10000000;
+  }
+  else if (idf2k <= 48)
+  {
+   idpdg=fPdg->ConvertGeant3ToPdg(idf2k);
+  }
+  else
+  {
+   if (idf2k==201) idpdg=12;
+   if (idf2k==202) idpdg=14;
+   if (idf2k==203) idpdg=16;
+   if (idf2k==204) idpdg=-12;
+   if (idf2k==205) idpdg=-14;
+   if (idf2k==206) idpdg=-16;
+  }
+
+  t.SetParticleCode(idpdg);
+  t.SetName(fPdg->GetParticle(idpdg)->GetName());
+  t.SetTitle("RECO track");
+  t.SetMass(fPdg->GetParticle(idpdg)->Mass());
+  t.SetCharge(fPdg->GetParticle(idpdg)->Charge()/3.);
+
+  // Retrieve the various fit parameters for this track
+  AliSignal* fitdata=fFitdefs->GetIdHit(i);
+  for (Int_t jval=0; jval<fEvent.fresult[i].nval; jval++)
+  {
+   fitdata->SetSignal(fEvent.fresult[i].val[jval],jval+1);
+  }
+
+  // Store the various fit parameters for this track
+  t.SetFitDetails(fitdata);
+
+  // Store the various reco tracks as track hypotheses.
+  // A copy of the first reco track is entered as a new track instance
+  // into the event and all reco tracks (incl. the first one) are
+  // stored as hypotheses linked to this new reco track.
+  if (i==0)
+  {
+   evt->AddTrack(t);
+   AliTrack* tx=evt->GetTrack(evt->GetNtracks());
+   Int_t nrec=evt->GetNtracks(1);
+   tx->SetId(nrec+1);
+  }
+  AliTrack* tx=evt->GetTrack(evt->GetNtracks());
+  if (tx) tx->AddTrackHypothesis(t);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::PutHits(IceEvent* evt)
+{
+// Get the hit and waveform info from the F2000 file into the IcePack structure.
+// This memberfunction is based on the original code by Adam Bouchta.
+
+ if (!evt) return;
+
+ // Loop over all the hits and add them to the current event
+ IceAOM om;
+ AliSignal s;
+ s.SetSlotName("ADC",1);
+ s.SetSlotName("LE",2);
+ s.SetSlotName("TOT",3);
+ Int_t chan=0;
+ Int_t maxchan=800;
+ if (fOmdb) maxchan=fHeader.nch;
+ IceAOM* omx=0;
+ AliSignal* sx=0;
+ Int_t tid=0;
+ AliTrack* tx=0;
+ for (Int_t i=0; i<fEvent.nhits; i++)
+ {
+  chan=fEvent.h[i].ch+1;
+  if (chan>maxchan) continue; // Channels 9001, 9002 etc are trigger channels
+
+  // Get corresponding device from the current event structure  
+  omx=(IceAOM*)evt->GetIdDevice(chan);
+  if (!omx)
+  {
+   if (fOmdb)
+   {
+    omx=(IceAOM*)fOmdb->GetObject(chan,1);
+    evt->AddDevice(omx);
+   }
+   else
+   {
+    om.Reset(1);
+    om.SetUniqueID(chan);
+    evt->AddDevice(om);
+   }
+   omx=(IceAOM*)evt->GetIdDevice(chan);
+  }
+
+  if (!omx) continue;
+
+  s.Reset();
+  s.SetUniqueID(fEvent.h[i].id);
+  s.SetSignal(fEvent.h[i].amp,1);
+  s.SetSignal(fEvent.h[i].t,2);
+  s.SetSignal(fEvent.h[i].tot,3);
+
+  omx->AddHit(s);
+
+  sx=omx->GetHit(omx->GetNhits());
+  if (!sx) continue;
+
+  // Bi-directional link between this hit and the track that caused the ADC value.
+  // This F2K info is probably only present for MC tracks.
+  tid=fEvent.h[i].ma;
+  if (tid > 0)
+  {
+   tx=evt->GetIdTrack(tid); // Reco tracks
+   if (!tx) tx=evt->GetIdTrack(-tid); // MC tracks
+   if (tx) sx->AddLink(tx);
+  }
+  else
+  {
+   if (tid == -2) s.SetNameTitle("N","Noise");
+   if (tid == -3) s.SetNameTitle("A","Afterpulse");
+  }
+ }
+
+ // Loop over all the waveforms and add the histo(s) to the corresponding OM's
+ TH1F histo;
+ Int_t nbins=0;
+ Float_t xlow=0;
+ Float_t xup=0;
+ TString hname;
+ for (Int_t iwf=0; iwf<fEvent.nwf; iwf++)
+ {
+  chan=fEvent.wf[iwf].om;
+  if (chan<=0 || chan>maxchan) continue; // Skip trigger channels
+
+  // Get corresponding device from the current event structure  
+  omx=(IceAOM*)evt->GetIdDevice(chan);
+  if (!omx)
+  {
+   if (fOmdb)
+   {
+    omx=(IceAOM*)fOmdb->GetObject(chan,1);
+    evt->AddDevice(omx);
+   }
+   else
+   {
+    om.Reset(1);
+    om.SetUniqueID(chan);
+    evt->AddDevice(om);
+   }
+   omx=(IceAOM*)evt->GetIdDevice(chan);
+  }
+
+  if (!omx) continue;
+
+  omx->SetSlotName("BASELINE",omx->GetNnames()+1);
+  omx->SetSignal(fEvent.wf[iwf].baseline,"BASELINE");
+
+  // Fill the waveform histogram
+  hname="OM";
+  hname+=chan;
+  hname+="-WF";
+  hname+=omx->GetNwaveforms()+1;
+
+  histo.Reset();
+  histo.SetName(hname.Data());
+  nbins=fEvent.wf[iwf].ndigi;
+  xlow=fEvent.wf[iwf].t_start;
+  xup=xlow+float(nbins)*fEvent.wf[iwf].t_bin;
+  histo.SetBins(nbins,xlow,xup);
+
+  for (Int_t jbin=1; jbin<=fEvent.wf[iwf].ndigi; jbin++)
+  {
+   histo.SetBinContent(jbin,fEvent.wf[iwf].digi[jbin]);
+  }
+
+  omx->SetWaveform(&histo,omx->GetNwaveforms()+1);
+ }
+
+ // Set bi-directional links between hits and reco track hypotheses.
+ // Note : Reco tracks are recognised by their positive id.
+ Int_t hid=0;
+ TObjArray* rectracks=evt->GetTracks(1);
+ for (Int_t jtk=0; jtk<rectracks->GetEntries(); jtk++)
+ {
+  tx=(AliTrack*)rectracks->At(jtk);
+  if (!tx) continue;
+  
+  for (Int_t jhyp=1; jhyp<=tx->GetNhypotheses(); jhyp++)
+  {
+   AliTrack* hypx=tx->GetTrackHypothesis(jhyp);
+   if (!hypx) continue;
+
+   // Loop over all combinations of F2K fits and used OM hits
+   for (Int_t k=0; k<fEvent.nfit_uses; k++)
+   {
+    if (fEvent.fit_uses[k].useid != hypx->GetId()) continue;
+    hid=fEvent.fit_uses[k].hitid;
+    sx=evt->GetIdHit(hid,"IceAOM");
+    if (sx) sx->AddLink(hypx);
+   }
+  }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
diff --git a/RALICE/icepack/iceconvert/IceF2k.h b/RALICE/icepack/iceconvert/IceF2k.h
new file mode 100644 (file)
index 0000000..68175c1
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef IceF2k_h
+#define IceF2k_h
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+#include "TObject.h"
+#include "TChain.h"
+#include "TFile.h"
+#include "TDatabasePDG.h"
+#include "TString.h"
+
+#include "AliObjMatrix.h"
+
+#include "IceAOM.h"
+#include "IceEvent.h"
+
+#include "rdmc.h"
+
+class IceF2k : public TObject
+{
+ public :
+  IceF2k(char* fname=0,Int_t split=0,Int_t bsize=32000);         // Constructor
+  virtual ~IceF2k();                                             // Destructor
+  void Loop(TTree* otree=0,Int_t nentries=-1,Int_t printfreq=1); // Perform the format conversion
+  TDatabasePDG* GetPDG();     // Provide pointer to the PDG database
+  AliObjMatrix* GetOMdbase(); // Provide pointer to the OM geometry, calib. etc... database
+  AliDevice* GetFitdefs();    // Provide pointer to the Fit definition parameters
+
+ protected :
+  Int_t fSplit; // The split level of the produced ROOT data file
+  Int_t fBsize; // The buffersize of the produced ROOT data file
+
+  TDatabasePDG* fPdg;  // Database with PDG information
+  AliObjMatrix* fOmdb; // Database of all OM devices with their geometry, calib. etc... data
+  AliDevice* fFitdefs; // Fit definitions as indicated in the header of the F2000 input file
+
+  void FillOMdbase();                // Fill geometry and calib. parameters of all devices
+  void SetFitdefs();                 // Set the fit definitions as used in the F2000 input file
+  void PutMcTracks(IceEvent* evt);   // Put the MC tracks from the F2000 file into the IcePack structure
+  void PutRecoTracks(IceEvent* evt); // Put the reconstructed tracks from the F2000 file into the IcePack structure
+  void PutHits(IceEvent* evt);       // Put the hits and waveforms from the F2000 file into the IcePack structure
+
+  mcfile* fInput;  //! Structure holding the input file characteristics
+  array   fHeader; //! Structure holding the file header info
+  mevt    fEvent;  //! Structure holding the actual event data (hits, tracks, etc...)
+
+ ClassDef(IceF2k,1) // Conversion of F2K data into IceEvent physics event structures.
+};
+#endif
diff --git a/RALICE/icepack/iceconvert/amanda.c b/RALICE/icepack/iceconvert/amanda.c
new file mode 100644 (file)
index 0000000..78a3bf0
--- /dev/null
@@ -0,0 +1,631 @@
+/*
+ * Read/write files in the oncoming Standard AMANDA format - "format 2000"
+ */
+#if 0 /******* TODO *********/
+/* skip event gets array as parameter   */
+/* level 4 event types in mevt  */
+/*   end of file, tend          */
+/******************************/        
+#endif
+
+
+char *amanda_rdmc_cvsid = 
+"$Header: /net/local/cvsroot/siegmund/rdmc/amanda.c,v 1.81 2004/02/19 17:10:08 wiebusch Exp $";
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "rdmc.h"
+#ifdef AMANDA_ASCII_F
+
+#include "rdmc_local.h"
+
+#include "amanda.h"
+#include "f2k.h"
+
+/****************************************************************************/
+/*       rdmc_nint(double a)                                                 */
+/* converts a to the nearest integer                                        */
+/* but also takes care on the sign                                          */
+/****************************************************************************/
+long rdmc_nint(double a)
+{ long i;
+  i =  (a >= 0.) ?  (long) (a + 0.5 ) : (long) (a - 0.5);
+ return  i;
+}
+
+/*******************************/
+/* Work around missing isnan() */
+/*******************************/
+int isnan(float r)
+{
+ return 0;
+}
+
+/******************************************************/
+/*** Definitions of f2k blocks struture in memory   ***/
+/******************************************************/
+
+
+/* check if line is in  buffer or read a new one */
+/* returns 0 if OK */
+static int amanda_readline(mcfile *fp);
+
+/* dump a line back into the buffer if it is empty */
+/* returns 0 if OK */
+static int amanda_unreadline(mcfile *fp);
+
+/* read the next block according to a list of allowed lines into the buffer */
+/* returns 0 if OK */
+static int amanda_read_block(mcfile *fp ,const f2000_event_t *def);
+
+/* try to decode a given line according to line_def */
+/* store if OK */
+/* returns RDMC_IO_OK or RDMC_LINE_EMPTY or RDMC_EVENT_NOT_RECOGNIZED */ 
+static int amanda_lex_line(mcfile *fp, const f2000_line_t * const line_def[F2K_MAX_LINETYPES] );
+
+/* compares each byte of key to the first no white exam until lngth of key*/
+/* -1 if line is empty, 0 on no and 1 on succes */
+static int tokencmp(const char *key, char *exam);
+
+/* same with no trailing chars */ 
+static int tokencmp_notrail(const char *key, char *exam);
+
+/* checks if the first non-white char in exam is in keys */
+/* if a line is only whitespace ot empty -1 is returned */
+/* 0: if the char is not found */
+/* 1: if the char is not found */
+static int tokenchr(const char *keys, char *exam);
+/* same as above but chars are not alnum (ispunct()) */
+static int tokenchrpunct(const char *keys, char *exam);
+
+/***************************************************************************/
+/***************************************************************************/
+/***                                                                     ***/
+/*** Read  functions follow                                              ***/
+/***                                                                     ***/
+/***************************************************************************/
+
+  
+/****************************************************************************
+ * read the F2000 "V" line (the first one) and put it into fp
+ ****************************************************************************/
+/******* This is the only parswer routine, which is different !!! */
+/* it reads directly from fp, instead of the readline mode */
+int rdmc_amanda_V(const char *s, mcfile *fp)
+{
+  int major = 0, minor = 0;
+  if(sscanf(s,"V 2000.%i.%i",&major, &minor) != 2) 
+    return RDMC_LINE_NOT_PARSED;
+  if (rdmc_is_f2000_supported(major, minor) == 0)
+    return  RDMC_UNKNOWN_FORMAT_VERSION;
+  fp->fmajor = major;
+  fp->fminor = minor;
+  return RDMC_IO_OK;
+
+} /* amanda_rdmc_V() */
+
+int rdmc_rhd_amanda(mcfile *fp){ 
+  const  f2000_event_t *ev_def;
+  int ret;
+
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  case 101:
+  case 102:
+  case 200401:
+    ev_def=&f2000_preamble_1x1;
+    break;
+  default:
+    return RDMC_UNKNOWN_FORMAT_VERSION;
+  }
+
+  /* read the block acordng to the def */
+  if ((ret = amanda_read_block(fp, ev_def)) != RDMC_IO_OK)
+    return ret;
+
+  /* use the pointer from  the event definition and scan*/
+  return ev_def->reader(fp, NULL, NULL);
+}
+
+
+int rdmc_rarr_amanda(mcfile *fp, array *ar)
+{ 
+  const  f2000_event_t *ev_def;
+  int ret;
+
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  case 101:
+  case 102:
+  case 200401:
+    ev_def=&f2000_mhead_1x1;
+    break;
+  default:
+    return RDMC_UNKNOWN_FORMAT_VERSION;
+  }
+
+  /* read the block acordng to the def */
+  if ((ret = amanda_read_block(fp, ev_def)) != RDMC_IO_OK)
+    return ret;
+
+  /* use the pointer from  the event definition and scan*/
+  return ev_def->reader(fp, ar, NULL);
+
+}
+
+int rdmc_revt_amanda(mcfile *fp, mevt *ev, array *ar){ 
+  const  f2000_event_t **ev_def,*foot_def;
+
+  int ret = RDMC_ILF;
+  int ret2 = RDMC_ILF;
+
+  /* get the config def for the right format*/
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  case 101:
+    ev_def = f2000_events_1x1;
+    foot_def =  &f2000_mfoot_1x1 ;
+    break;
+  case 102:
+    ev_def =f2000_events_1x2;
+    foot_def =  &f2000_mfoot_1x1 ;
+    break;
+  case 200401:
+    ev_def =f2000_events_2004x1;
+    foot_def =  &f2000_mfoot_1x1 ;
+    break;
+  default:
+    return RDMC_UNKNOWN_FORMAT_VERSION;
+  }
+
+  while( *ev_def !=NULL ){
+    /* read the block acordng to the def */
+    ret = amanda_read_block(fp, *ev_def);
+    if ( ret == RDMC_IO_OK)
+      break;
+    ++ev_def;
+  }
+  if ( ret == RDMC_IO_OK){
+    rdmc_clear_mevt(ev);                           /* reset the event */
+    /* use the pointer from  the event definition and scan*/
+    if (fp->info.f2000.nolex)
+      return RDMC_IO_OK;
+    else
+      return (*ev_def)->reader(fp, ar, ev);
+  }else{  /* test footer */
+    if ( ret == RDMC_EVENT_NOT_RECOGNIZED) {
+      ret2 = amanda_read_block(fp, foot_def);
+      if (ret2 == RDMC_IO_OK)
+       return RDMC_EOF;
+      else
+       return ret2;
+    }else{
+      return ret;
+    }
+  }
+}
+
+int rdmc_skipevt_amanda(mcfile *fp)
+{ 
+  int ret;
+#if 0
+  array ar;
+#endif
+  mevt ev;
+#if 0 /* this is the proper, presently slow version */
+  rdmc_init_array(&ar); 
+  rdmc_init_mevt(&ev);
+  fp->info.f2000.nolex=1;
+  ret = rdmc_revt_amanda(fp, &ev, &ar);
+  fp->info.f2000.nolex=0;
+  rdmc_clear_array(&ar);
+  rdmc_clear_mevt(&ev);
+#else /* presently no array is needed -> dirty patch ! */
+  rdmc_init_mevt(&ev);
+  fp->info.f2000.nolex=1;
+  ret = rdmc_revt_amanda(fp, &ev, NULL);
+  fp->info.f2000.nolex=0;
+  rdmc_clear_mevt(&ev);
+#endif
+  return ret;
+}
+
+
+
+/****************************************************************************
+ * Reads a nonempty line 
+ ****************************************************************************/
+static int amanda_readline(mcfile *fp){
+
+  char *s = fp->last_line;
+  do {
+    if (fp->info.f2000.unread != 0 ) { /* line in buffer */
+      fp->info.f2000.unread = 0;
+    } else{ /* no line in buffer - read from file */
+      if (fgets(s, RDMC_MAXLINE-1, fp->fp) == NULL)/*fgets includes the '\n'*/
+       return EOF;
+    }
+  } while (*s == '\0');      /* look for a not-empty line */
+  /* increment the counter line */
+  fp->fpos++;
+  return RDMC_IO_OK;
+
+} /* amanda_readline() */
+
+/****************************************************************************
+ * "unread" an amanda F2000 format line
+ ****************************************************************************/
+
+static int amanda_unreadline(mcfile *fp){
+  if (fp->info.f2000.unread != 0) 
+    return EOF; /* only one line allowed */
+  else
+    fp->info.f2000.unread = 1;
+  fp->fpos--;
+  return RDMC_IO_OK;
+} /* amanda_unreadline() */
+
+
+static int amanda_read_block(mcfile *fp ,const f2000_event_t *def){
+  int r;
+  int ret=RDMC_ILF;
+  int do_reading;
+  rdmc_clear_f2k_buffer(fp->info.f2000.f2k_buffer);
+  fp->errline = 0;
+
+  /* test if the block starts with the right line */
+  do_reading=1;
+  do {
+    if (def->opener[0]){  /* yes there is one needed ! */
+      if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
+       ret=r;
+      else /* analyse if this line matches and store it then */
+       ret = amanda_lex_line(fp, def->opener);
+    } else{ /* no opener needed  -> OK */
+      ret = RDMC_IO_OK;
+      break;
+    }
+    if( ret != RDMC_LINE_EMPTY ){ /* something happende */
+      do_reading=0;
+      if ( ret == RDMC_EVENT_NOT_RECOGNIZED){
+       amanda_unreadline(fp); /* we have read one line to much  */
+       return ret;
+      }
+    }
+  } while(do_reading);
+
+  /* keep on reading body lines  */
+  do_reading=1;
+  do {
+    /* analyse if this line matches and store it then */
+    if (def->inner[0]){  /* yes there are some  ! */
+      if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
+       ret =r;
+      else
+       ret = amanda_lex_line(fp, def->inner);
+    } else{ 
+      ret = RDMC_IO_OK;
+      do_reading=0;
+      break;
+    }
+
+    if( ret != RDMC_LINE_EMPTY ){ /* something happend */
+      if (ret == RDMC_IO_OK) /* line OK -> next one */
+       continue;
+      else{ /* line is not parsed -> check if an end marker appeared */
+       amanda_unreadline(fp); /* we have read one line to much  */
+       do_reading = 0; /* this is no error since the body may be empty */
+       ret = RDMC_IO_OK; /* this is no error but maybe  the next event */
+       break; /* ok we end here */
+      }
+    }
+  } while(do_reading);
+
+  /* check the end marker   */
+  do_reading=1;
+  do {
+    /* analyse if this line matches and store it then */
+    if (def->closer[0]){  /* yes there are some needed ! */
+      if ( (r=amanda_readline(fp)) != RDMC_IO_OK)
+       ret=r;
+      else
+       ret = amanda_lex_line(fp, def->closer);
+    } else{ 
+      ret = RDMC_IO_OK;
+      do_reading=0;
+      break;
+    }
+
+    if( ret != RDMC_LINE_EMPTY ){ /* something happend */
+      if (ret == RDMC_IO_OK){ /* line OK -> finish */
+       do_reading=0;
+       break;
+      }
+      else{ /* line is not parsed  */
+       amanda_unreadline(fp); /* we have read one line to much  */
+       do_reading = 0; /* this is no error since the body may be empty */
+       break; /* ok we end here */
+      }
+    }
+  } while(do_reading);
+
+  return ret;
+}
+
+
+static int amanda_lex_line(mcfile *fp, const f2000_line_t * const line_def[F2K_MAX_LINETYPES] ){
+  int ptindex , cres = 0;
+  const f2000_line_t *opt;
+
+  if ( !(line_def[0]) ) /* no match actually needed */
+    return RDMC_EVENT_NOT_RECOGNIZED;
+
+  for(ptindex=0 , cres=0, opt = line_def[0] 
+       ; opt 
+       ; opt = line_def[++ptindex] 
+      ){
+
+    switch (opt->searchtype){
+    case COMP_STRINGWISE:
+      cres = tokencmp(opt->tag,fp->last_line);
+      break;
+    case COMP_STRINGWISE_NOTRAIL:
+      cres = tokencmp_notrail(opt->tag,fp->last_line);
+      break;
+    case COMP_CHARWISE:
+      cres = tokenchr(opt->tag,fp->last_line);
+      break;
+    case COMP_CHARPUNCT:
+      cres = tokenchrpunct(opt->tag,fp->last_line);
+      break;
+#if 0
+    case COMP_DUMMY: /* no token is needed so stop parsing */
+      /* trap to finish here */
+      return RDMC_EVENT_NOT_RECOGNIZED;
+      break;
+#endif
+    default:
+      return RDMC_LIBRARY_ERROR;
+    } /* switch */
+    if (cres < 0){ /* empty line */
+      return RDMC_LINE_EMPTY;
+    } else if(cres == 0){ /* no match found */
+      /* needed but not found -> try the next */
+      continue;
+    }else{ /* ok tag is found */
+      rdmc_push_f2k_buffer(fp->info.f2000.f2k_buffer, fp->last_line,line_def[ptindex]); 
+      return RDMC_IO_OK;
+    } /* check cres */
+  } /*for */
+  return RDMC_EVENT_NOT_RECOGNIZED;
+}
+
+/* compares each byte of key to exam until th lngth of key */
+/* leading whitespaces are ignored */
+static int tokencmp(const char *key, char *exam){
+  int r = -1;
+  const char *k = key;
+  const char *e = exam;
+  while(*e){
+    if (isspace(*e))
+      ++e;
+    else { /* this is the first non white */
+      r=0;
+      while (*k){ /* now check key */
+       if (!(*e)) /* if e ends before key */ 
+         return r=0;
+       if( *e == *k ) /* stil agreement ? */
+         r=1;
+       else
+         return r=0; /* break if not */
+       ++e; /* next char */
+       ++k;
+      } /* while k */
+      return r; /*  exit here likely with r==1  */
+    } 
+  } /* while e */
+
+  return r;
+}
+/* compares each byte of key to exam until the lngth of key */
+/* trailing chars are ignored */
+static int tokencmp_notrail(const char *key, char *exam){
+  int r = -1;
+  const char *k = key;
+  const char *e = exam;
+  while(*e){
+    if (isspace(*e))
+      ++e;
+    else { /* this is the first non white */
+      r=0;
+      while (*k){ /* now check key */
+       if (!(*e)) /* if e ends before key */ 
+         return r=0;
+       if( *e == *k ) /* stil agreement ? */
+         r=1;
+       else
+         return r=0; /* break if not */
+       ++e; /* next char */
+       ++k;
+      } /* while k */
+      return r; /*  exit here likely with r==1  */
+    } 
+  } /* while e */
+  return r;
+}
+
+/* checks if the first non-white char in exam is in keys */
+/* if a line is only whitespace ot empty -1 is returned */
+/* 0: if the char is not found */
+/* 1: if the char is found */
+static int tokenchr(const char *keys, char *exam){
+  int r = -1;
+  const char *k=keys;
+  const char *e=exam;
+  while(*e){
+    if (isspace(*e))
+      ++e;
+    else { /* this is the first non white */
+      r=0;
+      while (*k){ /* now check key */
+       if( *e == *k ) /* agreement ? */
+         return r=1;
+       else
+         ++k;
+      } /* while k */
+      return r=0; /*  exit here likely with r==1  */
+    } 
+  } /* while e */
+  return r;
+}
+
+static int tokenchrpunct(const char *keys, char *exam){
+  int r = -1;
+  const char *k=keys;
+  const char *e=exam;
+  while(*e){
+    if (isspace(*e))
+      ++e;
+    else if (!ispunct(*e))
+      return r=0;
+    else { /* this is the first non white */
+      r=0;
+      while (*k){ /* now check key */
+       if( *e == *k ) /* agreement ? */
+         return r=1;
+       else
+         ++k;
+      } /* while k */
+      return r=0; /*  exit here likely  */
+    } 
+  } /* while e */
+  return r;
+}
+
+
+/***************************************************************************/
+/***                                                                     ***/
+/*** Write functions follow                                              ***/
+/***                                                                     ***/
+/***************************************************************************/
+/***************************************************************************/
+
+
+
+
+/***************************************************************************/
+/* write end of file (F2000 format)                                        */
+int rdmc_wrend_amanda(const mcfile *fp)
+{
+  const  f2000_event_t *ev_def;
+
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  case 101:
+  case 102:
+  case 200401:
+    ev_def=&f2000_mfoot_1x1;
+    break;
+  default:
+    return RDMC_UNKNOWN_FORMAT_VERSION;
+  }
+
+  /* use the pointer from  the event definition and scan*/
+  return ev_def->writer(fp, NULL, NULL);
+} /* wrend_amanda() */
+
+/****************************************************************************
+ * function warr_amanda() writes the array info to a amanda-like file
+ * This function writes out the head of a AMANDA ascii file
+ * opposite to reading the input file it writes not only
+ * the Geometry banks ('G', 'P') , but also the ('V' and 'M' flags)
+ * so the function whd_amanda does not exist
+ ****************************************************************************/
+
+int rdmc_warr_amanda(const mcfile *fp,const array *geo)
+{
+  const  f2000_event_t *ev_def;
+
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  default:
+    ev_def=&f2000_mhead_1x1;
+    break;
+  }
+
+  /* use the pointer from  the event definition and scan*/
+  return ev_def->writer(fp, geo, NULL);
+}
+
+/****************************************************************************
+ * function wevt_amanda() writes an event to a amanda-like file
+ ****************************************************************************/
+
+int rdmc_wevt_amanda(const mcfile *fp,const mevt *event, const array *ar)
+{
+  const  f2000_event_t *ev_def;
+
+  /* get the config def for the right format*/
+  switch( 100*fp->fmajor + fp->fminor ){
+  case 101:
+    ev_def=f2000_events_1x1[0]; /* take first array element */
+    break;
+  case 102:
+    ev_def=f2000_events_1x2[0]; /* take first array element */
+    break;
+  case 200401:
+    ev_def=f2000_events_2004x1[0]; /* take first array element */
+    break;
+  default:
+    return RDMC_UNKNOWN_FORMAT_VERSION;
+  }
+
+  /* use the pointer from  the event definition and scan*/
+  return ev_def->writer(fp, ar, event);
+
+}
+
+#if 0
+/****************************************************************************
+ * wrhist_amanda() writes history lines to an ASCII file
+ ****************************************************************************/
+
+int rdmc_wrhist_amanda(const mcfile *fp, const char *s, const char *pre)
+{
+  return rdmc_wrhist_f2k_1x1(fp, s, pre);
+}
+
+/****************************************************************************
+ * wrcomment_amanda() writes a comment line to an ASCII file
+ ****************************************************************************/
+
+int rdmc_wrcomment_amanda(const mcfile *fp, const char *s)
+{
+  return rdmc_wrcomment_f2k_1x1(fp, s);
+}
+#endif
+
+#endif /* AMANDA_ASCII_F */
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
+/* 
+   This is just for EMACS:
+   Local Variables:
+   compile-command: "cd .. ; make -k rdmc" 
+   End: 
+*/
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RALICE/icepack/iceconvert/amanda.h b/RALICE/icepack/iceconvert/amanda.h
new file mode 100644 (file)
index 0000000..d93b356
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _RDMC_AMANDA_H
+#define _RDMC_AMANDA_H
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+#include <malloc.h>
+
+#define PID180 (M_PI/180.)
+
+#define SEC_PER_DAY 86400
+
+
+
+int rdmc_amanda_V(const char *s, mcfile *fp);
+
+int rdmc_rhd_amanda(mcfile *fp);   /* reads the format info from the file */
+int rdmc_rarr_amanda(mcfile *fp, array *ar);   /* (amanda/f2000 ascii file) */
+
+int rdmc_warr_amanda(const mcfile *fp, const array *ar);      /* (amanda) */
+int rdmc_wrend_amanda(const mcfile *fp);    /* write end of file (F2000 format) */
+
+#if 0
+/* writes the arry of coment lines essentially as they are */
+int rdmc_wrcomment_amanda(const mcfile *fp, const char *s);           /* (amanda) */
+/* writes an array of lines but puts prefix (e.g. "HI ") before each line */
+int rdmc_wrhist_amanda(const mcfile *fp, const char *s, const char *prefix);
+#endif
+
+int rdmc_skipevt_amanda(mcfile *fp);                                 /* (amanda) */
+int rdmc_revt_amanda(mcfile *fp, mevt *ev, array *ar);/* (amanda/f2000 ascii) */
+int rdmc_wevt_amanda(const mcfile *fp, const mevt *ev, const array *ar);/* amanda */
+
+
+#endif
+
+
diff --git a/RALICE/icepack/iceconvert/baikal.c b/RALICE/icepack/iceconvert/baikal.c
new file mode 100644 (file)
index 0000000..7162ea2
--- /dev/null
@@ -0,0 +1,1062 @@
+/*
+ * Read/write files in the BAIKAL formats
+ * Zeuthen: Krabi/Wischnewski
+ * Moscow: an older Nora/Belolaptikov format (only reading)
+ */
+
+char *baikal_rdmc_cvsid = 
+"$Header: /net/local/cvsroot/siegmund/rdmc/baikal.c,v 1.20 2000/02/07 13:02:17 ole Exp $";
+
+#include <stdio.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+////////////#include <unistd.h>
+
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "rdmc.h"
+
+#include "rdmc_local.h"
+#include "baikal.h"                /* function prototyping */
+
+
+#ifndef DEBUG
+#define DEBUG 0                       /* DEBUG 1 writes some info to stderr */
+#endif
+
+#define ERRLINE (-__LINE__)
+
+#define PID180 (M_PI/180.)
+
+#ifdef BAIKAL_BIN_F
+
+#define BAIKAL_PMTPERCHANNEL 2
+
+
+
+
+static void  rdmc_add_fitdef_baikal(array *ar);
+
+
+/****************************************************************************/
+/* The function rarr_mc() reads the header of a baikal like file            */
+/****************************************************************************/
+
+int rdmc_rarr_baikal_mc(mcfile *fp, array *ar)
+{
+  
+  int nw;                                       /* number of words to read */
+  int ptr;                    /* pointer to the current word in the header */
+  int i,j;                                               /* loop variables */
+  int *iclust;              /* pointer to current channel number in string */
+  
+  rdmc_init_array(ar);                                  /* reset the array */
+
+/**************************** the array info *******************************/
+  ar->nrun=fp->info.bai.nrun;
+
+  ptr = 0;
+  if (fp->info.bai.fortran_recs) 
+    rdmc_mcgeti(fp);                              /* skip fortran record header */
+  nw = rdmc_mcgeti(fp);                                /* 1: number of words    */
+
+  if (nw <= 2) {             /* too less words: nonreconstructed data file */
+    ar->id = NT_36;                               /* default: baikal array */
+    ar->nch = 0;                              /* no telescope info aviable */
+    ar->nstr = 0;
+    rdmc_mcseek(fp, nw - ptr);                        /* read the unused fields */
+    if (fp->info.bai.fortran_recs)
+      rdmc_mcgeti(fp);                                          /* unused dummy */
+    return 0;                                                /* and return */
+  } /* if nw <= 2 */
+
+  rdmc_mcseek(fp,2);                                      /* here unused values */
+  ar->nch = rdmc_mcgetf(fp);                           /* 3: number of channels */
+  ar->nstr = rdmc_mcgetf(fp);                          /* 4: number of strings  */
+  if (ar->nch <= 18)
+    ar->id = NT_36;
+  else if (ar->nch <= 36)
+    ar->id = NT_72;
+  else if (ar->nch <= 48)
+    ar->id = NT_96;
+  else if (ar->nch <= 72)
+    ar->id = NT_144;
+  else if (ar->nch <= 96)
+    ar->id = NT_192;
+  else
+    ar->id = NT_200;
+  ptr += 4;                                                /* 3 words read */
+  
+  if (nw < ptr + ar->nch * 5) return ERRLINE;            /* invalid format */
+  if (ar->nch > RDMC_MAXCHANNELS) return ERRLINE;
+  if (ar->nch <= 0) return ERRLINE;
+  if (ar->nstr <= 0) return ERRLINE;
+
+  iclust = (int *)calloc(ar->nstr,sizeof(int)); 
+                                         /* alloc mem for channel nr array */
+
+/*************************** Channel position and parameters ***************/
+
+  for (i = 0; i < ar->nch; i++) {
+    ar->x[i] = rdmc_mcgetf(fp)/100.0;                            /* coordinates */
+    ar->y[i] = rdmc_mcgetf(fp)/100.0;                       /* in meters of the */
+    ar->z[i] = rdmc_mcgetf(fp)/100.0;                           /* i-th channel */
+    ar->costh[i] = rdmc_mcgetf(fp);                                /* cos theta */
+    ar->str[i] = rdmc_mcgetf(fp);                              /* string number */
+    ar->type[i] = QUASAR;                              /* default pmt type */
+    ar->clust[i] = iclust[ar->str[i] - 1]++;             /* channel number */
+  } /* for i */
+  ptr += 5 * ar->nch;
+  ar->is_calib.geo=1;
+
+  free (iclust);                       /* free the mem for the ch nr array */
+
+/****************************** Pmt parameters *****************************/
+
+  if (nw < ptr + ar->nch * 2 * BAIKAL_PMTPERCHANNEL) return ERRLINE;
+  for (i = 0; i < ar->nch; i++) {
+    ar->thresh[i] = rdmc_mcgetf(fp);                  /* threshold for each pmt */
+    ar->sensit[i] = rdmc_mcgetf(fp);                 /* sensitivity of each pmt */
+    for (j = 1; j < BAIKAL_PMTPERCHANNEL; j++) {
+      rdmc_mcgetf(fp);                                /* threshold for each pmt */
+      rdmc_mcgetf(fp);                               /* sensitivity of each pmt */
+    } /* for j */
+    ar->serial[i] = 0;                                 /* no serial number */
+  } /* for i */
+  ptr += ar->nch * 2 * BAIKAL_PMTPERCHANNEL;
+
+  rdmc_mcseek(fp, nw - ptr);                      /* read the last unused fields */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcgeti(fp);                                            /* unused dummy */
+
+  rdmc_add_fitdef_baikal(ar);
+
+  return 0;
+
+} /* function rarr_mc() */
+
+/****************************************************************************/
+/* revt_baikal() tries to read the different BAIKAL dialects                */
+/****************************************************************************/
+int rdmc_revt_baikal(mcfile *fp, mevt *ev, const array *ar)
+{
+  long filepos;                         /* shows the current file position */
+  int r;
+
+  filepos = ftell(fp->fp);                    /* store the file position */
+
+  if (fp->info.bai.mc) {                   /* if it is (probably) a mc file */
+    r = rdmc_revt_baikal_mc(fp,ev,ar);                    /* try to read as an mc event */
+    if (r < EOF) {
+      fseek(fp->fp,filepos,SEEK_SET);        /* set to old file position */
+      r = rdmc_revt_baikal_data(fp,ev,ar);             /* try to read as data file */
+      if (r == 0)                               /* if it was successfull */
+       fp->info.bai.mc = 0;                      /* set file type to data */
+      else                                                     /* if not */
+       fseek(fp->fp,filepos,SEEK_SET);         /* restore file position */
+    } /* if r == ILF */
+  } /* if mc file */
+  
+  else {                              /* if it is (probably) a data file */
+    r = rdmc_revt_baikal_data(fp,ev,ar);             /* try to read as data event */
+    if (r < EOF) {                                        /* if it fails */
+      fseek(fp->fp,filepos,SEEK_SET);        /* set to old file position */
+      r = rdmc_revt_baikal_mc(fp,ev,ar);           /* try to read as an mc event */
+      if (r == 0)                               /* if it was successfull */
+       fp->info.bai.mc = 1;                     /* set file type to mc */
+      else                                                     /* if not */
+       fseek(fp->fp,filepos,SEEK_SET);         /* restore file position */
+    } /* if r == ILF */
+  } /* if data file */
+  
+  fp->fpos = ftell(fp->fp);         /* store file position for debugging */
+
+  /* now update stuff which was not included in the data */
+  /* now uopdate the channel and srtring reference of the event */
+  ev->nch = rdmc_count_nch(ev);         /* calc the number of hit channels */
+  rdmc_fill_mhit_str(ev,ar);            /* fill the mhit->str fields */
+  ev->nstr = rdmc_count_nstr(ev);      /* calc the number of hit channels */
+
+
+
+  return r;
+
+} /* revt_baikal() */
+
+/****************************************************************************/
+/* revt_mc() reads the next *mc*-event                                      */
+/* it is just a switch to the correct routines (moscow/zeuthen format)      */
+/****************************************************************************/
+
+int rdmc_revt_baikal_mc(mcfile *fp, mevt *ev, const array *ar)
+{
+  switch(fp->fmajor) {
+  case BAIKAL_OLD:
+  case BAIKAL_NEW:
+    return rdmc_revt_baikal_zeu(fp,ev,ar);
+  case BAIKAL_MOS:
+    return rdmc_revt_baikal_mos(fp,ev,ar);
+  default:
+    return ERRLINE;
+  }
+  
+} /* function revt_mc() */
+
+/****************************************************************************/
+/* revt_zeu() reads the zeuthen formats (BAIKAL_OLD,BAIKAL_NEW)             */
+/****************************************************************************/
+
+int rdmc_revt_baikal_zeu(mcfile *fp, mevt *ev, const array *ar)
+{
+
+  int nw;                                       /* number of words to read */
+  int ptr = 0;                /* pointer to the current word in the header */
+  int i;                                                  /* loop variable */
+
+  rdmc_clear_mevt(ev);                                  /* clear old event info */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);                           /* skip fortran record header */
+
+  nw = rdmc_mcgeti(fp) - 1;                    /* number of words in the record */
+  if (feof(fp->fp)) return EOF;                       /* file end reached? */
+
+  if (nw < 8)  return ERRLINE;
+
+/***************** read the first (common) informations ********************/
+
+  ev->t_offset = 0.0;                     /* time offset in baikal is zero */
+
+  if (fp->fmajor == BAIKAL_NEW) {                    /* for the new format */
+    i = rdmc_mcgeti(fp);
+    ev->nhits = i % 1000;           /* number of hits (higher part is nrun)*/
+    ev->nrun = i/1000;
+    ev->enr = rdmc_mcgeti(fp);                                  /* event number */
+    fp->info.bai.enr = ev->enr;
+    ptr += 2;
+  } /* if new format */
+  else {                                             /* for the old format */
+    ev->nrun = ar->nrun;
+    ev->enr = ++(fp->info.bai.enr);                         /* set dummies */
+  } /* if old format */
+  
+/************ allocate memory for generated track and fill it **************/
+
+  { 
+    mtrack gen;
+    rdmc_init_mtrack(&gen);
+    gen.costh = rdmc_mcgetf(fp);                   /* cos theta + 10 * nhits */
+
+    if (fp->fmajor == BAIKAL_OLD) {                    /* for the old format */
+      ev->nhits = (fabs(gen.costh)+2.0)/10;      /* fill the nr of hits */
+      if (ev->nhits == 0) return ERRLINE;         /* there must be >= 1 hit! */
+    } /* if old format */
+    else                                               /* for the new format */
+      if ((int)((fabs(gen.costh)+2.0)/10.0) != ev->nhits) return ERRLINE; 
+                                                         /* test for nhits */ 
+    gen.costh = fmod(gen.costh,10.);
+                                           /* this is now really cos theta */
+    gen.phi = rdmc_mcgetf(fp)*PID180;                          /* phi in rad */
+    gen.x = rdmc_mcgetf(fp)/100.0;                               /* read the */
+    gen.y = rdmc_mcgetf(fp)/100.0;                            /* coordinates */
+    gen.z = rdmc_mcgetf(fp)/100.0;                           /* of the track */
+    gen.e = rdmc_mcgetf(fp)*1000.0;                         /* Energy in MeV */
+    gen.id = MUON_PLUS;                           /* we generated muons */
+    gen.tag = 1;
+    gen.length = RDMC_BIG;                          /* infinity track length */
+    rdmc_tau_tr(&gen);                      /* calc the direction cosinuus */
+    rdmc_add_gen(ev,&gen,0);
+  }
+  ptr += 5;                                     /* increase record pointer */
+
+  if (nw < ptr + ev->nhits * 3 + 2)       /* if there are not enough words */
+    return ERRLINE;
+
+/************* allocate memory for the hits and fill them ******************/
+
+  if (ev->nhits > 0)
+    ev->h = malloc(ev->nhits * sizeof(mhit)); 
+                                              /* allocate mem for the hits */
+  for (i = 0; i < ev->nhits; i++)
+    rdmc_init_mhit( &(ev->h[i]));
+  for (i = 0; i < ev->nhits; i++) {
+    ev->h[i].ch = rdmc_mcgetf(fp);                         /* contains ch and m */
+    ev->h[i].ma = ev->h[i].ch/10000;                 /* the first 2 digits */
+    ev->h[i].mt = fmod(ev->h[i].ch/100,100.);        /* the digits 3 and 4 */
+    ev->h[i].ch = fmod(ev->h[i].ch,100.);             /* the last 2 digits */
+    ev->h[i].ch--;                          /* for "C" style (index 0,...) */
+    ev->h[i].amp = rdmc_mcgetf(fp);                                /* amplitude */
+    ev->h[i].t = rdmc_mcgetf(fp);                                       /* time */
+    ev->h[i].tot = -1.0;                             /* no TOT information */
+  } /* for i */
+
+
+  rdmc_mcseek(fp, 1);                                         /* one dummy word */
+  ev->gen->t = rdmc_mcgetf(fp);                  /* time corresponding gen->xyz */
+  ev->gen->nmuon = ev->ntrack;                           /* number of muons */
+
+  if (ev->gen->costh < -1.5) {            /* if costh = -2 (no gen. track) */
+    free(ev->gen);                                  /* free the gen. track */
+    ev->gen = NULL;                                   /* reset the pointer */
+    ev->ntrack = 0;                    /* set the number of tracks to zero */
+  } /* if costh < -1.5 */
+
+  ptr += ev->nhits * 3 + 2;
+
+  if (nw <= ptr + 2) {                             /* if no reconstruction */
+    ev->nfit = 0;                       /* number of reconstr. tracks is 0 */
+    rdmc_mcseek(fp, nw-ptr);                   /* read the last (unused) fields */
+    if (fp->info.bai.fortran_recs)
+      rdmc_mcseek(fp, 1);             /* read the field used for fortran format */
+    return 0;
+  } /* if no reco */
+
+  if (nw < ptr + 10) return ERRLINE;
+
+/*********** allocate memory for reconstructed track and fill it ***********/
+
+  {
+    mtrack rec;
+    mevt_special_t fresult;
+    rdmc_init_mtrack(&rec);
+    rdmc_init_fit_jk(&fresult,1);
+
+    rec.costh = rdmc_mcgetf(fp);             /* cos theta, or -99 if no reco */
+    rec.phi = rdmc_mcgetf(fp)*PID180;                   /* reconstructed phi */
+    rec.x = rdmc_mcgetf(fp)/100.0;                   /* reconstructed vertex */
+    rec.y = rdmc_mcgetf(fp)/100.0;
+    rec.z = rdmc_mcgetf(fp)/100.0;
+    rec.t = rdmc_mcgetf(fp);                           /* corresponding time */
+    rec.id = MUON_PLUS;                       /* we reconstructed muons */
+    rec.e = 0.0;                             /* no energy reconstructed */
+    rec.length = RDMC_BIG;                          /* infinity track length */
+    rec.nmuon = 1;                                 /* default: one muon */
+    rec.tag = 1;
+    rdmc_tau_tr(&rec);                       /* calc the direction cosinuus */
+
+    /************** read jaanus' reconstruction results ************************/
+    
+    fresult.val[JK_SIGTH] = rdmc_mcgetf(fp);
+    fresult.val[JK_COVMAX] = rdmc_mcgetf(fp);
+    fresult.val[JK_COVMIN] = fmod(fresult.val[JK_COVMAX],1000.)/1000.;
+    fresult.val[JK_COVMAX] = (fresult.val[JK_COVMAX] /1000. 
+                             - fresult.val[JK_COVMIN])/1000.;
+    fresult.val[JK_CUTFLAG] = rdmc_mcgetf(fp);
+    fresult.val[JK_FITID] = 
+      fp->info.bai.rec_vers + 10000 * fp->info.bai.min_vers;
+    ptr += 9;
+    
+    rdmc_mcseek(fp, nw-ptr);                     /* read the last (unused) fields */
+
+    fresult.val[JK_RCHI2] = -1.0; /* in the baikal format is no rchi2  */
+    fresult.val[JK_CHI2] = -1.0;    /* in the baikal format is no chi2 */
+    fresult.val[JK_PROB] = -1.0;    /* in the baikal format is no prob */
+    
+    if (rec.costh >= -2.0)  {                     /* if cos theta is -99 */
+      rdmc_add_fit(ev,&rec,&fresult,0);
+    }
+  } /* read reco */
+  
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);           /* read the field used for fortran format */
+  
+  return 0;
+  
+} /* function revt_zeu() */
+
+/****************************************************************************/
+/* revt_mos() reads the next moscow format event (BAIKAL_MOS)               */
+/****************************************************************************/
+
+int rdmc_revt_baikal_mos(mcfile *fp, mevt *ev, const array *ar)
+{
+
+  int nw;                                       /* number of words to read */
+  int ptr = 0;                /* pointer to the current word in the header */
+  int i,j;                                                /* loop variable */
+  int nint;                            /* number of interactions of a muon */
+  mtrack gentrack;                       /* struct to hold the first track */
+
+  rdmc_clear_mevt(ev);                                  /* clear old event info */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);                           /* skip fortran record header */
+
+  nw = rdmc_mcgeti(fp) - 1;                    /* number of words in the record */
+  if (feof(fp->fp)) return EOF;                       /* file end reached? */
+
+  if (nw < 9)  return ERRLINE;
+
+/***************** read the first (common) informations ********************/
+
+  ev->t_offset = 0.0;                     /* time offset in baikal is zero */
+
+
+  ev->nhits = rdmc_mcgetf(fp);                                /* number of hits */
+  ev->nrun = 0;                                 /* no run number is stored */
+  ev->enr = ++(fp->info.bai.enr);         /* event number from file pointer */
+  ptr += 1;
+
+/************ read the first generated track (central muon) ****************/
+
+  rdmc_init_mtrack(&gentrack);
+  gentrack.costh = -cos(rdmc_mcgetf(fp)*PID180);                   /* cos theta */
+  gentrack.phi = (180.0+rdmc_mcgetf(fp))*PID180;                  /* phi in rad */
+  if (gentrack.phi > 360.0) gentrack.phi -= 360.0;       /* phi in (0,360) */
+  gentrack.x = rdmc_mcgetf(fp);                                  /* read the */
+  gentrack.y = rdmc_mcgetf(fp);                               /* coordinates */
+  gentrack.z = rdmc_mcgetf(fp);                              /* of the track */
+  gentrack.t = rdmc_mcgetf(fp);                        /* time of the vertex */
+  gentrack.id = MUON_PLUS;                           /* we generated muons */
+  gentrack.length = RDMC_BIG;                       /* infinity track length */
+  gentrack.nmuon = 1;                      /* one muon produces this track */
+  gentrack.tag=1;
+  rdmc_tau_tr(&gentrack);                     /* calc the direction cosinuus */
+  gentrack.e = rdmc_mcgetf(fp) * 1e3;                       /* Energy in MeV */
+  ev->ntrack = (int)rdmc_mcgetf(fp) % 100;               /* number of tracks */
+                                                /* higher part is nmuonall */
+  rdmc_mcgetf(fp);                          /* one dummy ("EMMAX + 1000* ESUM") */
+  ptr += 8;                                     /* increase record pointer */
+
+/******* allocate memory for generated track(s) and fill them **************/
+
+#if 0 /* i dont know if I really need the first track (axis) */
+  ev->ntrack++;                 /* one additional track for the group axis */
+#endif
+
+  if (ev->ntrack > 0)
+    ev->gen = malloc(ev->ntrack*sizeof(mtrack));
+                                       /* allocate mem for generated track */
+
+#if 0 /* i dont know if I really need the first track (axis) */
+  memcpy(ev->gen,&gentrack,sizeof(mtrack)); /* fill the first track (axis) */
+
+  for (i = 1; i < ev->ntrack; i++){                      /* for all tracks */
+#else
+  for (i = 0; i < ev->ntrack; i++){                      /* for all tracks */
+#endif
+    rdmc_init_mtrack(ev->gen+i);
+    nint = rdmc_mcgetf(fp);               /* read the number of interactions */
+    ev->gen[i].costh = gentrack.costh;                            /* theta */
+    ev->gen[i].phi = gentrack.phi;                 /* and phi are the same */
+    ev->gen[i].t = gentrack.t;                        /* and the time, too */
+    ev->gen[i].x = rdmc_mcgetf(fp);                           /* koordinates */
+    ev->gen[i].y = rdmc_mcgetf(fp);                                /* of the */
+    ev->gen[i].z = rdmc_mcgetf(fp);                                /* vertex */
+    rdmc_tau_tr(ev->gen+i);                   /* calc the direction cosinuus */
+    ev->gen[i].nmuon = 1;                  /* one muon produces this track */
+    ev->gen[i].length = RDMC_BIG;                        /*infinity length */
+    ev->gen[i].id = MUON_PLUS;
+    ev->gen[i].tag = i+1;
+    ev->gen[i].e = 0.0;                           /* reset the muon energy */
+    ptr += 4;                                              /* 4 words read */
+    for (j = 0; j < nint; j++) {                   /* for all interactions */
+      ev->gen[i].e += rdmc_mcgetf(fp)*1e3;        /* add the interaction energy */
+      rdmc_mcseek(fp,3);                          /* skip the interaction point */
+      ptr += 4;                                            /* 4 words read */
+    } /* for j */
+
+  } /* for i */
+  
+  ev->gen[0].e = gentrack.e;       /* the first track gets all muon energy */
+
+  if (nw < ptr + ev->nhits * 5)           /* if there are not enough words */
+    return ERRLINE;
+
+/************* allocate memory for the hits and fill them ******************/
+
+  if (ev->nhits > 0)
+    ev->h = malloc(ev->nhits * sizeof(mhit)); 
+  for (i = 0; i < ev->nhits; i++) {
+    rdmc_init_mhit(&(ev->h[i]));
+  } 
+            /* allocate mem for the hits */
+  for (i = 0; i < ev->nhits; i++) {
+    ev->h[i].ch = rdmc_mcgetf(fp);                        /* channel number */
+    ev->h[i].ma = ((int)rdmc_mcgetf(fp)+1000) % 1000;   /* amp-defining muon */
+    ev->h[i].mt = ((int)rdmc_mcgetf(fp)+1000) % 1000;  /* time-defining muon */
+    ev->h[i].ch--;                          /* for "C" style (index 0,...) */
+    ev->h[i].amp = rdmc_mcgetf(fp);                            /* amplitude */
+    ev->h[i].t = rdmc_mcgetf(fp);                                  /* time */
+    ev->h[i].tot = -1.0;                             /* no TOT information */
+  } /* for i */
+
+  ptr += ev->nhits * 5;
+
+  rdmc_mcseek(fp, nw-ptr);                 /* read the last (unused) fields */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);         /* read the field used for fortran format */
+
+  return 0;
+
+} /* function revt_mos() */
+
+/****************************************************************************/
+/* revt_data() reads the next *data* event                                  */
+/****************************************************************************/
+
+int rdmc_revt_baikal_data(mcfile *fp, mevt *ev, const array *ar)
+{
+
+  int nw;                                       /* number of words to read */
+  int ptr = 0;                /* pointer to the current word in the header */
+  int i;                                                  /* loop variable */
+
+  rdmc_clear_mevt(ev);                                  /* clear old event info */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);                           /* skip fortran record header */
+
+  nw = rdmc_mcgeti(fp);                        /* number of words in the record */
+  if (feof(fp->fp)) return EOF;                       /* file end reached? */
+
+  if (nw < 2)  return ERRLINE;
+
+/***************** read the first (common) informations ********************/
+
+  i = rdmc_mcgeti(fp);                     /* number of channels and run number */
+  ev->nhits = fmod(i,1000.);                         /* number of channels */
+  ev->nrun = i/1000;                                         /* run number */
+
+  ev->enr = rdmc_mcgeti(fp);                                    /* event number */
+  fp->info.bai.enr = ev->enr;
+  ev->ntrack = 0;                                         /* no generation */
+
+  ptr += 2;
+  if (ptr + 3*ev->nhits > nw)/* if there are not enough words for hit info */
+    return ERRLINE;
+
+/************* allocate memory for the hits and fill them ******************/
+
+  if (ev->nhits > 0)
+    ev->h = malloc(ev->nhits * sizeof(mhit)); 
+  for (i = 0; i < ev->nhits; i++) { /* init */
+    rdmc_init_mhit( &(ev->h[i]));
+  }
+
+  for (i = 0; i < ev->nhits; i++) {                  /* read the hit infos */
+    ev->h[i].ch = rdmc_mcgetf(fp);                        /* channel nr (1,...) */
+    ev->h[i].ch--;                          /* for "C" style (index 0,...) */
+    ev->h[i].amp = rdmc_mcgetf(fp);                    /* amplitude of this hit */
+    ev->h[i].t = rdmc_mcgetf(fp);                           /* time of this hit */
+    ev->h[i].mt = ev->h[i].ma = RDMC_NA;       /* there is no particle info */
+    ev->h[i].tot = -1.0;                             /* no TOT information */
+  } /* for i */
+
+
+  ptr += 3*ev->nhits;
+  if (nw <= ptr + 2) {                             /* if no reconstruction */
+    ev->nfit = 0;                                        /* reset fit flag */
+    rdmc_mcseek(fp, nw-ptr);                   /* read the last (unused) fields */
+    if (fp->info.bai.fortran_recs)
+      rdmc_mcseek(fp, 1);             /* read the field used for fortran format */
+    return 0;
+  } /* if no reco */
+
+  if (nw < ptr + 9) return ERRLINE;
+
+/*********** allocate memory for reconstructed track and fill it ***********/
+  {
+    mtrack rec;
+    mevt_special_t fresult;
+
+    rdmc_init_mtrack(&rec);
+    rdmc_init_fit_jk(&fresult,1);
+
+    rec.costh = rdmc_mcgetf(fp);             /* cos theta, or -99 if no reco */
+    rec.phi = rdmc_mcgetf(fp)*PID180;                   /* reconstructed phi */
+    rec.x = rdmc_mcgetf(fp)/100.0;              /* reconstructed coordinates */
+    rec.y = rdmc_mcgetf(fp)/100.0;                        /* of track origin */
+    rec.z = rdmc_mcgetf(fp)/100.0;
+    rec.t = rdmc_mcgetf(fp);           /* reconstructed time of track origin */
+    rec.id = MUON_PLUS;                       /* we reconstructed muons */
+    rec.e = 0.0;                             /* no energy reconstructed */
+    rec.length = RDMC_BIG;                       /* infinity track length */
+    rec.nmuon = 1;                                 /* default: one muon */
+    rec.tag = 1;
+    rdmc_tau_tr(&rec);                    /* calc the direction cosinuus */
+
+
+/************** read jaanus' reconstruction results ************************/
+
+    fresult.val[JK_SIGTH] = rdmc_mcgetf(fp);
+    fresult.val[JK_COVMAX] = rdmc_mcgetf(fp);
+    fresult.val[JK_COVMIN] = fmod(fresult.val[JK_COVMAX],1000.)/1000.;
+    fresult.val[JK_COVMAX] = (fresult.val[JK_COVMAX] /1000. 
+                                - fresult.val[JK_COVMIN])/1000.;
+    fresult.val[JK_CUTFLAG] = rdmc_mcgetf(fp);
+    ptr += 9;
+
+    rdmc_mcseek(fp, nw-ptr);            /* read the last (unused) fields */
+    
+    fresult.val[JK_RCHI2] = -1.0; /* in the baikal format is no rchi2  */
+    fresult.val[JK_CHI2] = -1.0;    /* in the baikal format is no chi2 */
+    fresult.val[JK_PROB] = -1.0;    /* in the baikal format is no prob */
+    
+    if (ev->rec->costh >= -2.0)  {                 /* if cos theta is -99 */
+      rdmc_add_fit(ev,&rec,&fresult,0);
+    } /* if no reco */
+  }
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcseek(fp, 1);       /* read the field used for fortran format */
+  return 0;
+  
+} /* function revt_data() */
+
+/****************************************************************************/
+/* warr_mc() writes the array info to the baikal-like file                  */
+/****************************************************************************/
+
+int rdmc_warr_baikal_mc(mcfile *fp, const array *ar)
+{
+  int nw;
+  int i,j;
+  double mc_ind_muon, mc_id_spec;                       /* Jaanus' mc flags */
+  double mc_vers ;
+
+  nw = 14 + ar->nch * (5 + 2 * BAIKAL_PMTPERCHANNEL);    /* number of words */
+  if (fp->info.bai.fortran_recs)           /* if it is a formatted fortran file */
+    rdmc_mcputi(4 * nw + 4, fp);                      /* write the record length */
+
+  rdmc_mcputi(nw, fp);                 /* write the number of words as first int */
+  
+  rdmc_mcputf(0.0, fp);                                   /* write something (?) */
+
+  mc_vers=atof(fp->info.bai.mc_vers);
+  mc_vers = ((int) mc_vers) % 10000 ;
+  rdmc_mcputf(mc_vers + 10000.0 * fp->fmajor, fp);         /* format version */
+  rdmc_mcputf((double)ar->nch, fp);
+  rdmc_mcputf((double)ar->nstr, fp);
+
+  for (i = 0; i < ar->nch; i++) {                       /* for all channels */
+    rdmc_mcputf(100.0*ar->x[i], fp);
+    rdmc_mcputf(100.0*ar->y[i], fp);
+    rdmc_mcputf(100.0*ar->z[i], fp);
+    rdmc_mcputf(ar->costh[i], fp);
+    rdmc_mcputf((double)ar->str[i], fp);
+  } /* for i */
+
+  for (i = 0; i < ar->nch; i++) {
+    for (j = 0; j < BAIKAL_PMTPERCHANNEL; j++) {
+      rdmc_mcputf(ar->thresh[i], fp);               /* threshold for each pmt */
+      rdmc_mcputf(ar->sensit[i], fp);              /* sensitivity of each pmt */
+   } /* for j */
+  } /* for i */
+
+  rdmc_mcputf((double)rdmc_o_rdateconv(fp->info.bai.time), fp); /* write time in YYMMDD format */
+
+#if 0
+  /* igen does contain the random seed since ASCII version -6 */
+  mc_ind_muon = fp->info.bai.igen /10000;
+  mc_id_spec = fp->info.bai.igen % 10000;
+#else
+  mc_ind_muon=mc_id_spec=0.;
+#endif
+
+  rdmc_mcputf(mc_ind_muon, fp);
+  rdmc_mcputf(mc_id_spec, fp);
+  rdmc_mcputf((double)fp->info.bai.igtrack, fp);
+  rdmc_mcputf(0.0, fp);
+  rdmc_mcputf(0.0, fp);
+
+  rdmc_mcputf((double)fp->info.bai.nw_rec_arr, fp);
+  rdmc_mcputf((double)fp->info.bai.nw_rec_evt, fp);
+  rdmc_mcputf((double)fp->info.bai.rec_vers, fp);
+  rdmc_mcputf((double)fp->info.bai.min_vers, fp);
+
+  if (fp->info.bai.fortran_recs)                     /* if it is a formatted fortran file */
+    rdmc_mcputi(4 * nw + 4, fp);                      /* write the record length */
+
+#if (DEBUG == 1)
+    fprintf(stderr, "<Write><Header: nch=%i nstr=%i>\n",ar->nch,ar->nstr);
+#endif
+
+  return errno;
+
+} /* function warr_mc() */
+
+/****************************************************************************/
+/* function wevt_mc() writes an event to  file                              */
+/****************************************************************************/
+
+int rdmc_wevt_baikal_mc(mcfile *fp, const mevt *ev, const array *ar)
+{
+  int nw;                                                /* number of words */
+  int i;                                                   /* loop variable */
+  
+  nw = 20 + 3*ev->nhits;
+
+  if (fp->info.bai.fortran_recs)            /* record length for formatted files */
+    rdmc_mcputi(4*nw+4,fp);
+  
+/***************** write the first (common) informations ********************/
+
+  rdmc_mcputi(nw,fp);                           /* first word is number of words */
+  if (fp->fmajor == BAIKAL_NEW) {                     /* for the new format */
+    rdmc_mcputi(ev->nhits+1000*ev->nrun,fp);
+    rdmc_mcputi(ev->enr,fp);
+  } /* if new format */
+
+/******************* write the generating track *****************************/
+
+  if (ev->ntrack > 0) {                   /* if there is a generating track */
+    if (ev->gen[0].costh > 0)
+      rdmc_mcputf(ev->nhits*10.0+ev->gen[0].costh, fp);
+    else
+      rdmc_mcputf(-ev->nhits*10.0+ev->gen[0].costh, fp);
+    rdmc_mcputf(ev->gen[0].phi/PID180, fp);
+    rdmc_mcputf(ev->gen[0].x*100.0, fp);
+    rdmc_mcputf(ev->gen[0].y*100.0, fp);
+    rdmc_mcputf(ev->gen[0].z*100.0, fp);
+    rdmc_mcputf(ev->gen[0].e/1000.0, fp);               /* baikal: energy in GeV */
+  } /* if gen */
+  else {                                          /* if no generating track */
+    rdmc_mcputf(-ev->nhits*10.0-2.0, fp);            /* seems to be not good ole */
+/*    mcputf(ev->nhits*10.0, fp); */        /* this could be an alternative */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+  } /* if not gen */
+
+/***************************** write the hits *******************************/
+
+  for (i = 0; i < ev->nhits; i++) {                           /* store hits */
+    rdmc_mcputf(ev->h[i].ch+1.0+ev->h[i].mt*100.0+ev->h[i].ma*10000.0, fp);
+    rdmc_mcputf((double)ev->h[i].amp, fp);
+    rdmc_mcputf((double)ev->h[i].t, fp);
+  }
+  
+  rdmc_mcputf(1.0, fp);                                /* I dont know what it is */
+
+  if (ev->ntrack > 0)                     /* if there is a generating track */
+    rdmc_mcputf(ev->gen[0].t, fp);         /* time for origin of generated track */
+  else
+    rdmc_mcputf(0.0, fp);
+
+/******************* write the reconstructed track **************************/
+  
+  if (ev->nfit > 0) {                      /* if there is a reconstrunction */
+    rdmc_mcputf(ev->rec[0].costh, fp);
+    rdmc_mcputf(ev->rec[0].phi/PID180, fp);
+    rdmc_mcputf(ev->rec[0].x*100.0, fp);
+    rdmc_mcputf(ev->rec[0].y*100.0, fp);
+    rdmc_mcputf(ev->rec[0].z*100.0, fp);
+    rdmc_mcputf(ev->rec[0].t, fp);
+    if ( (ev->fresult != NULL)              /* if there is an jk record */
+        && (0 <= ev->fresult->id )
+        && (ar->n_fit > ev->fresult->id )  /* there is a fit defined  */
+        && (rdmc_is_this_jk(&(ar->def_fit[ev->fresult->id])
+                               ,ev->fresult) ) )    {
+      rdmc_mcputf(ev->fresult->val[JK_SIGTH], fp);
+      rdmc_mcputf(ev->fresult->val[JK_COVMIN]*1e3 
+            + 1e6*ev->fresult->val[JK_COVMAX], fp);
+      rdmc_mcputf(ev->fresult->val[JK_CUTFLAG], fp);
+    } /* if res */
+    else {                                      /* if there is no jk record */
+      rdmc_mcputf(0.0, fp);                                   /* set all to zero */
+      rdmc_mcputf(0.0, fp);                                   /* set all to zero */
+      rdmc_mcputf(0.0, fp);                                   /* set all to zero */
+    } /* if not res */
+  } /* if reconstruction */
+  else {                                   /* if there is no reconstruction */
+    rdmc_mcputf(-99., fp);
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+    rdmc_mcputf(0.0, fp);                                     /* set all to zero */
+  } /* if no reconstruction */
+
+  if (fp->fmajor == BAIKAL_NEW)
+    rdmc_mcputi(0, fp);                           /* flag for further subrecords */
+
+  if (fp->info.bai.fortran_recs)            /* record length for formatted files */
+    rdmc_mcputi(4*nw+4,fp);
+  
+  return 0;
+
+} /* function wevt() */
+
+
+/****************************************************************************/
+/* function wevt_data() writes an event to file                             */
+/****************************************************************************/
+
+int rdmc_wevt_baikal_data(mcfile *fp, const mevt *ev, const array *ar)
+{
+
+  return rdmc_wevt_baikal_mc(fp,ev,ar);         /* we use mc format instead of data format */
+
+} /* function wevt_data() */
+
+/****************************************************************************/
+/* rhd_mc() reads the format relevant informations for baikal-like formats, */
+/*          and then rewinds                                                */
+/****************************************************************************/
+
+int rdmc_rhd_baikal_mc(mcfile *fp) 
+{
+  long i1,i2;
+  float f1,f2,f3,f4;
+
+  i1 = rdmc_mcgeti(fp);
+  i2 = rdmc_mcgeti(fp);
+  
+  if ((i1 == i2*4+4) || (rdmc_swap(i1) == rdmc_swap(i2) * 4 + 4)){/* if the first int */
+    fp->info.bai.fortran_recs = 1;  /* contains the record length -> fortran file */
+  }
+  rewind(fp->fp);                               /* rewind file to the begin */
+  if (fp->info.bai.fortran_recs) rdmc_mcseek(fp,1);  /* skip the fortran record header */
+  i1 = rdmc_mcgeti(fp);                /* contains the number of words in header */
+  if (i1 == 2) {                             /* if there are only two words */
+    fp->info.bai.mc = 0;              /* it is a non-reconstrcted data file */
+    fp->info.bai.nrun = rdmc_mcgetf(fp);                  /* first word is the run number */
+    fp->info.bai.time = 0;                                /* no time stored */
+    fp->info.bai.rec_vers = 0;                         /* no reconstruction */
+    fp->info.bai.min_vers = 0;                           /* no minimization */
+    rewind(fp->fp);                                      /* rewind the file */
+    return 0;                                                 /* and return */
+  } /* if i1 = 2 */
+  f1 = rdmc_mcgetf(fp);                                             /* dummy a(1)*/
+  f2 = rdmc_mcgetf(fp);                        /* contains mc and format version */
+  f3 = rdmc_mcgetf(fp);                                    /* number of channels */
+  f4 = rdmc_mcgetf(fp);                                 /* the number of strings */
+
+  if ((f4 != (int)f4)                                /* should be a integer */
+    ||(f4 <= 0.0)                                     /* and greater than 0 */
+    ||(f4 > 20.0)) {    /* and less than 20 (we havn't such big telescopes) */
+      fp->info.bai.swap = 1;              /* perhaps the bytes are swapped */
+    }                                         /* try it with swapped bytes! */
+  rewind(fp->fp);                               /* rewind file to the begin */
+  if (fp->info.bai.fortran_recs) rdmc_mcseek(fp,1); /* skip the fortran record header */
+  i1 = rdmc_mcgeti(fp);                /* contains the number of words in header */
+  if (i1 <= 2) {                             /* if there are too less words */
+    fp->info.bai.mc = 0;              /* it is a non-reconstrcted data file */
+    fp->info.bai.nrun = rdmc_mcgetf(fp);       /* first word is the run number */
+    fp->info.bai.time = 0;                               /* no time stored */
+    fp->info.bai.rec_vers = 0;                         /* no reconstruction */
+    fp->info.bai.min_vers = 0;                           /* no minimization */
+    rewind(fp->fp);                                      /* rewind the file */
+    return 0;                                                 /* and return */
+  } /* if i1 = 2 */
+  f1 = rdmc_mcgetf(fp);                                            /* dummy a(1) */
+  f2 = rdmc_mcgetf(fp);                        /* contains mc and format version */
+  f3 = rdmc_mcgetf(fp);                                    /* number of channels */
+  f4 = rdmc_mcgetf(fp);                                 /* the number of strings */
+
+  fp->fmajor = (int) f2 / 10000;           /* format version in second word */
+  fp->fminor = 0;
+  sprintf(fp->info.bai.mc_vers,"%i", ((int) f2) % 10000);
+
+  if ((f1 >= 0.9) && (f1 <= 10.0)&& (fp->fmajor == BAIKAL_OLD))
+    fp->fmajor = BAIKAL_MOS;              /* 1.0 as 1st word: moscow format */
+
+  rdmc_mcseek(fp, (int)f3*9);                               /* skip the pmt data */
+  fp->info.bai.time = rdmc_o_dateconv(rdmc_mcgetf(fp));            /* time in sec since 1.1.70 */
+  fp->info.bai.igen = 10000 * rdmc_mcgetf(fp);               /* k+2 is mc model */
+  fp->info.bai.igen += rdmc_mcgetf(fp);                    /* k+3 is mc spectrum */
+  if (fp->info.bai.igen >= 10000 )
+    fp->info.bai.igen = 103;
+  else
+    fp->info.bai.igen = 0;
+#if 0
+  fp->igtrack = rdmc_mcgetf(fp);                            /* k+4 is mc trigger */
+#else
+  fp->info.bai.nrun = rdmc_mcgetf(fp); /*ignore them */
+#endif
+  rdmc_mcseek(fp, 2);                                             /* two dummies */
+#if 0
+  fp->info.bai.nrun = fp->igtrack;                      /* it seems to be so */
+#endif
+
+  i1 -= 10 + f3 * 9;              /* decrease the header length s a pointer */
+
+  if (i1-- > 0) fp->info.bai.nw_rec_arr = rdmc_mcgetf(fp);
+  if (i1-- > 0) fp->info.bai.nw_rec_evt = rdmc_mcgetf(fp);
+  if (i1-- > 0) fp->info.bai.rec_vers = rdmc_mcgetf(fp);
+  if (i1-- > 0) fp->info.bai.min_vers = rdmc_mcgetf(fp);
+
+  rewind(fp->fp);                            /* rewind the file so that one */
+                                       /* starts reading from the beginning */
+  fp->info.bai.mc_id = (fp->info.bai.mc) ? 'U':'D';
+
+  return 0;
+
+} /* function rhd_mc() */
+
+
+/****************************************************************************/
+/* mcgeti() reads an 4 byte int from a mc/data file                         */
+/****************************************************************************/
+
+long rdmc_mcgeti(mcfile *fp)
+{
+
+  long r;
+  fread(&r, sizeof(r), 1, fp->fp);
+  return (fp->info.bai.swap)? rdmc_swap(r):r;
+
+} /* function rdmc_mcgeti() */
+
+
+/****************************************************************************/
+/* mcputi() writes an 4 bytes int to a mc/data file                         */
+/****************************************************************************/
+
+long rdmc_mcputi(long i, mcfile *fp)
+{
+  long r;
+
+  r = (fp->info.bai.swap)? rdmc_swap(i) : i;
+  fwrite(&r, sizeof(r), 1, fp->fp);
+  return r;
+
+} /* function mcputi() */
+
+
+/****************************************************************************/
+/* mcgetf() reads a 4 byte float form a mc/data file                        */
+/* attention: altough mcgetf() reads a float it returns double according to */
+/* the C standard                                                           */
+/****************************************************************************/
+
+double rdmc_mcgetf(mcfile *fp)
+{
+
+  union {
+    long r;
+    float f;
+  } u;
+
+  fread(&u.r, sizeof(u.r), 1, fp->fp);
+
+  if (fp->info.bai.swap) u.r = rdmc_swap(u.r);
+  return (double)u.f;
+
+} /* function mcgetf() */
+
+
+/****************************************************************************/
+/* mcputf() writes a 4 byte float to a mc/data file                         */
+/* attention: altought mcputf writes a 4 byte float, it requires a double   */
+/* argument because this is standard in C                                   */
+/****************************************************************************/
+
+double rdmc_mcputf(double d, mcfile *fp)
+{
+
+  union {
+    long r;
+    float f;
+  } u;
+
+
+  u.f = d;
+  if (fp->info.bai.swap) u.r = rdmc_swap(u.r);
+  fwrite(&u.r, sizeof(u.r), 1, fp->fp);
+
+  return d;
+
+} /* function mcgetf() */
+
+
+/****************************************************************************/
+/* mcseek() seeks over a number of 4-byte-words (int, float)                */
+/****************************************************************************/
+
+int rdmc_mcseek(mcfile *fp, long n)
+{
+
+  if (feof(fp->fp)) return EOF;
+
+  return fseek(fp->fp, n * sizeof(long), SEEK_CUR);
+
+} /* function mcseek() */
+
+/****************************************************************************/
+/* skipevt_baikal_mc() skips to the next record (event) in a baikal mc/data file   */
+/****************************************************************************/
+
+int rdmc_skipevt_baikal_mc(mcfile *fp)
+{
+
+  int nw;                          /* number of words in the current record */
+  int r;                                                    /* return value */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcgeti(fp);
+
+  nw = rdmc_mcgeti(fp);
+  if (nw < 0) return ERRLINE;
+
+  r = rdmc_mcseek(fp,nw);
+
+  fp->info.bai.enr++;                              /* increase event number */
+
+  if (fp->info.bai.fortran_recs)
+    rdmc_mcgeti(fp);
+
+  return r;
+
+} /* function skipevt_mc() */
+
+/****************************************************************************/
+/* swap() swaps the high and low bytes of a 4 byte int                      */
+/****************************************************************************/
+
+long rdmc_swap(long i)
+{
+
+  union {
+    unsigned char c[sizeof(long)];
+    long l;
+  } u;                                          /* help unions for swapping */
+  unsigned char r;
+
+  int n;
+
+  u.l = i;
+
+  for (n = 0; n < sizeof(long)/2; n++) { /* for all bytes in the first half */
+    r = u.c[n];                                      /* swap the first byte */
+    u.c[n] = u.c[sizeof(long) - n - 1];                    /* with the last */
+    u.c[sizeof(long) - n - 1] = r;
+  } /* for n */
+
+  return u.l;
+
+} /* function swap() */
+
+static void  rdmc_add_fitdef_baikal(array *ar){
+
+  array_hdef_t def_fit;
+
+  rdmc_jk_to_fitdef(&def_fit, 1);
+  rdmc_add_fit_def(ar,&def_fit, 0);
+}
+
+
+#endif /* BAIKAL_BIN_F */
+/****************************************************************************/
+/********************************** E O F ***********************************/
+/****************************************************************************/
+/* 
+   This is just for EMACS:
+   Local Variables:
+   compile-command: "cd .. ; make -k rdmc" 
+   End: 
+*/
diff --git a/RALICE/icepack/iceconvert/baikal.h b/RALICE/icepack/iceconvert/baikal.h
new file mode 100644 (file)
index 0000000..5ca0ecf
--- /dev/null
@@ -0,0 +1,34 @@
+
+#ifndef _RDMC_BAIKAL_H
+#define _RDMC_BAIKAL_H
+
+int rdmc_rarr_baikal_mc(mcfile *fp,array *ar);         /* (baikal mc/data file) */
+
+int rdmc_revt_baikal(mcfile *fp, mevt *ev, const array *ar);        /* (baikal) */
+int rdmc_revt_baikal_mc(mcfile *fp, mevt *ev, const array *ar);  /* (baikal mc) */
+int rdmc_revt_baikal_data(mcfile *fp, mevt *ev, const array *ar);/* (baikal data)*/
+int rdmc_revt_baikal_zeu(mcfile *fp, mevt *ev, const array *ar);/* (zeuthen format) */
+int rdmc_revt_baikal_mos(mcfile *fp, mevt *ev, const array *ar); /* (moscow format) */
+
+int rdmc_skipevt_baikal_mc(mcfile *fp);                             /* (baikal mc/data) */
+
+int rdmc_warr_baikal_mc(mcfile *fp, const array *ar);               /* (baikal mc/data) */
+
+int rdmc_wevt_baikal_mc(mcfile *fp, const mevt *ev, const array *ar);   /* (baikal mc) */
+int rdmc_wevt_baikal_data(mcfile *fp, const mevt *ev, const array *ar);  /* (baikal data) */
+int rdmc_wevt_baikal_mos(mcfile *fp, const mevt *ev, const array *ar);  /* (moscow format) */
+
+int rdmc_wrcomment_baikal_mc(const mcfile *fp, const char *s); /* (baikal, just a dummy) */
+
+int rdmc_rhd_baikal_mc(mcfile *fp);  /* reads the format info from the file */
+
+
+long rdmc_mcgeti(mcfile *fp);                            /* reads a int (4 byte) */
+long rdmc_mcputi(long i, mcfile *fp);                   /* writes a int (4 byte) */
+double rdmc_mcgetf(mcfile *fp);                /* reads a float (4 byte) from fp */
+double rdmc_mcputf(double r, mcfile *fp);       /* writes a float (4 byte) to fp */
+int rdmc_mcseek(mcfile *fp, long n);                /* seeks over n 4-byte-words */
+long rdmc_swap(long i);                                       /* swaps the bytes */
+
+
+#endif
diff --git a/RALICE/icepack/iceconvert/dumand.c b/RALICE/icepack/iceconvert/dumand.c
new file mode 100644 (file)
index 0000000..daebd83
--- /dev/null
@@ -0,0 +1,1268 @@
+/*
+ * Read/write files in the SiEGMuND native format
+ */
+
+char *dumand_rdmc_cvsid = 
+"$Header: /net/local/cvsroot/siegmund/rdmc/dumand.c,v 1.29 2004/04/15 14:45:51 wiebusch Exp $";
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+////////////////#include <unistd.h>
+
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(OSF1) || defined(AIX) || defined (SunOS)
+#include <errno.h>
+#endif
+
+#if defined(OSF1) || defined (SunOS) || defined (IRIX)
+#include <alloca.h>
+#endif
+
+#include "rdmc.h"
+
+#ifdef DUMAND_ASCII_F
+
+#include "rdmc_local.h"
+
+#include "dumand.h"
+
+#if RDMC_MAXTOKEN_PER_LINE < 100
+#define DUMAND_USER_MAX RDMC_MAXTOKEN_PER_LINE
+#else
+#define DUMAND_USER_MAX 100
+#endif
+
+#define DUMAND_MAXUSER_PER_LINE 15
+
+
+#ifndef DEBUG
+#define DEBUG 0                       /* DEBUG 1 writes some info to stderr */
+#endif
+
+#define ERRLINE (-__LINE__)
+
+#define PID180 (M_PI/180.)
+
+static int rdmc_a_M(const char *s, mcfile *fp);                /* read the several */
+static int rdmc_a_G(const char *s, array *ar);               /* from a dumand-like */
+static int rdmc_a_P(const char *s, array *ar);                           /* format */
+static int rdmc_a_K(const char *s, array *ar);
+static int rdmc_a_Q(const char *s, array *ar);
+static int rdmc_a_E(const char *s, mevt *ev);
+static int rdmc_a_H(const char *s, mhit *h); 
+static int rdmc_a_T(const char *s, mtrack *t);
+static int rdmc_a_F(const char *s, mtrack *t, mevt_special_t *fit);   
+static int rdmc_a_U(const char *s, mevt_special_t **user, int *nuser);
+static int rdmc_a_C(const char *s, char **comment);
+#if 0
+static int a_skip_C(mcfile *fp);                     /* skip comment lines */
+#endif
+static int parse_fit_def_ascii(array *ar, const char *s);   
+/* parse the fit definitions */
+static int  declare_rdmc_dumand_user(array *ar); 
+
+
+/****************************************************************************/
+/* The function rarr_ascii() reads the header of a dumand like file         */
+/****************************************************************************/
+
+int rdmc_rarr_ascii(mcfile *fp, array *ar)
+{
+  char s[RDMC_MAXLINE];                                /* input line */
+  int c;                                        /* first char of input line */
+  int ich = 0;                                              /* loop variable */
+  int *iclust;               /* pointer to current channel number in string */
+  int retval;                                                /* returnvalue */
+
+  rdmc_init_array(ar);                                      /* reset the array */
+  ar->nrun=fp->info.dum.nrun;
+  for (*s=c=getc(fp->fp); strchr("CGQ", *s) && (c != EOF); *s=c=getc(fp->fp)) {
+    if (fgets(s+1, RDMC_MAXLINE-1, fp->fp) == NULL)
+      return EOF;
+    fp->fpos++;
+
+    switch (*s) {
+    case 'C':
+      if ((retval = rdmc_a_C(s,&(ar->comment))))
+       return retval;
+      break;
+    case 'Q':
+      if ((retval = rdmc_a_Q(s, ar)))                 /* read trigger info */
+       return retval;
+      break;
+    case 'G':
+      if ((retval = rdmc_a_G(s, ar)))                 /* read array info */
+       return retval;
+      break;
+    } /* switch *s */
+  } /* while noe P nor V or E */
+
+  ungetc(c, fp->fp); /* ungetch the last char */
+  
+  if (ar->nstr == 0) ar->nstr = 1;                    /* minimal one string */
+
+  iclust = calloc(ar->nstr,sizeof(int));  /* alloc mem for channel nr array */
+
+  for (*s = c = getc(fp->fp); (*s != 'E') && (c != EOF); *s=c=getc(fp->fp)) {
+                                  /* for all lines *not* beginning with 'E' */
+    ungetc(c, fp->fp);
+    do {                                     /* read optional comment lines */
+      *s = c = getc(fp->fp);
+      if (c == EOF)
+       return EOF;
+      if (toupper((int) *s) != 'C')
+       break;
+
+      if (fgets(s+1, RDMC_MAXLINE-1, fp->fp) == NULL)
+       return EOF;
+      fp->fpos++;
+    } while (rdmc_a_C(s,&(ar->comment)) == 0);
+
+    if (*s == 'E') break;
+    ungetc(c, fp->fp);
+
+    fp->fpos += 1;
+    if (fgets(s,RDMC_MAXLINE,fp->fp) == NULL)              /* try to read a line */
+      return EOF;
+  
+    if ((retval = rdmc_a_P(s,ar)) != 0)                /* read pmt position */
+      return retval;
+
+    if ((retval = rdmc_a_K(s,ar)) != 0)                    /* read pmt calib */
+      return retval;
+
+    if ((retval = rdmc_a_Q(s,ar)) != 0)                 /* read trigger pars */
+      return retval;
+
+#if 0   /* does not work */
+    if ((retval = rdmc_a_C(s,&(ar->comment))) != 0)                 /* read trigger pars */
+      return retval;
+#endif
+
+  } /* while !e */
+
+  if (c != EOF) 
+    ungetc(*s, fp->fp);
+
+  for (ich = 0; ich < ar->nch; ich++) {
+
+    if ((ar->str[ich] < 0) && (ar->str[ich] <= ar->nstr)){
+                                                       /* str nr is in range */
+
+      if (ar->clust[ich] == -1)      /* if there was no valid channel number */
+       ar->clust[ich] = iclust[ar->str[ich] - 1];           /* generate one */
+
+      iclust[ar->str[ich] - 1] = ar->clust[ich] + 1;  /* increase channel nr */
+    } /* if str <= nstr */
+
+  } /* for ich */
+
+  free (iclust);                        /* free the mem for the ch nr array */
+
+  /* this is a dirty patch */
+  /* at the time of reading a header in dumand format we do not know */
+  /* the number of fits ! */
+  /* The (only ?) possible solution is to parse the history lines */
+  parse_fit_def_ascii(ar,fp->creator);   /* parse the fit definitions */
+
+  /* this durty patch just declares a default USER Tag rdmc when reading
+     dumand format */
+  declare_rdmc_dumand_user(ar); 
+
+  /* now patch the fp->M creation time into ar->tbegin */
+  ar->tbegin=fp->info.dum.time;
+
+  return 0;                                           /* successfull return */
+
+} /* function rarr_ascii() */
+
+/****************************************************************************/
+/* revt_ascii() reads the next dumand-like event                            */
+/****************************************************************************/
+
+int rdmc_revt_ascii(mcfile *fp, mevt *ev, const array *ar)
+{
+
+  char s[RDMC_MAXLINE];                                            /* input line */
+  int c;                                                      /* first char */
+  int ihit = 0, itrack = 0;                            /* hit/track counter */
+  int i;
+
+  rdmc_clear_mevt(ev);                                   /* clear old event info */
+
+  if (feof(fp->fp))                          /* if file end already reached */
+    return EOF;
+
+  ev->nrun = ar->nrun;                       /* copy the run number from fp */
+
+  do {                                            /* read optional comments */
+    *s = c = getc(fp->fp);
+    if (c == EOF)
+      return EOF;
+    if (toupper((int) *s) != 'C') {
+      ungetc(c, fp->fp);
+      break;
+    }
+    if (fgets(s+1, RDMC_MAXLINE-1, fp->fp) == NULL)
+      return EOF;
+    fp->fpos++;
+  } while (rdmc_a_C(s,&(ev->comment)) == 0);
+
+  *s = c = getc(fp->fp);                                     /* read a char */
+  if (c == EOF)
+    return EOF;
+  while (*s != 'E') {                      /* it should be an 'E' ("event") */
+    if (fgets(s+1, RDMC_MAXLINE-1, fp->fp) == NULL)
+      return EOF;
+    fp->fpos++;
+    *s = c = getc(fp->fp);
+    if (c == EOF)
+      return EOF;
+  } /* while != 'E' */
+
+  fp->fpos += 1;
+  if (fgets(s+1,RDMC_MAXLINE-1,fp->fp) == NULL)        /* try to read first line */
+    return EOF;
+
+  if (rdmc_a_E(s, ev) != 0)                      /* scan for the event info */
+    return ERRLINE;
+    
+  if (ev->ntrack > 0){
+    ev->gen = malloc(ev->ntrack*sizeof(mtrack));
+                                       /* allocate mem for generated tracks */
+    for (i=0 ; i < ev->ntrack ; i++)
+      rdmc_init_mtrack(ev->gen+i);
+  }
+
+  if (ev->nhits > 0){                          /* allocate mem for the hits */
+    ev->h = malloc(ev->nhits * sizeof(mhit)); 
+    for (i=0 ; i < ev->nhits ; i++)
+      rdmc_init_mhit(ev->h + i);
+  }
+
+  for (*s = c = getc(fp->fp); (*s != 'E') && (c != EOF); *s=c=getc(fp->fp)) {
+                                  /* for all lines *not* beginning with 'E' */
+    fp->fpos += 1;
+    if (fgets(s+1,RDMC_MAXLINE-1,fp->fp) == NULL) {        /* try to read a line */
+      c = EOF;
+      break;
+    }
+
+    switch (s[0]) {                /* switch for the first char of the line */
+    case 'F':                                                   /* fit line */
+      {
+       mtrack fit;
+       mevt_special_t res;
+
+       rdmc_init_mtrack(&fit);
+       rdmc_init_fit_jk(&res,RDMC_NA);
+       if (rdmc_a_F(s, &fit, &res) != 0)
+         return ERRLINE;
+       fit.tag=ev->nfit+1; /* nfit is still 0..nfit -1 but we want 1..nfit*/
+       res.id=ev->nfit;   /* reference to fit_def so 0..nfit-1 is OK */
+       if (rdmc_add_fit(ev,&fit,&res,ev->nfit))
+         return ERRLINE;
+      }
+      break;
+    case 'H':                                                        /* hit */
+      if (++ihit > ev->nhits)         /* dont fill more hits than allocated */
+       return ERRLINE;
+      if (rdmc_a_H(s, &(ev->h[ihit-1])) != 0)              /* scan this hit */
+       return ERRLINE;
+      ev->h[ihit-1].id=ihit;
+      break;
+    case 'T':                                           /* generating track */
+      if (++itrack > ev->ntrack)    /* dont fill more tracks than allocated */
+       return ERRLINE;
+      if (rdmc_a_T(s, &(ev->gen[itrack-1])) != 0)        /* scan this track */
+       return ERRLINE;
+      break;
+    case 'U':                                                 /* user-def'd */
+      if (rdmc_a_U(s, &(ev->user), &(ev->nuser)) != 0) 
+                                    /* look for rdmc-compatible user fields */
+       return ERRLINE;
+      break;                                                  /* is ignored */
+    case 'C':
+      rdmc_a_C(s, &(ev->comment));
+      break;
+    case 'V':                                               /* header flags */
+    case 'M':                                                        /* are */
+    case 'G':                                                        /* NOT */
+    case 'P':                                                    /* allowed */
+      return ERRLINE;
+    default:
+      break;
+    } /* switch s[0] */
+
+  } /* for all lines not beginning with 'E' */
+
+  if (ev->nhits > ihit) ev->nhits = ihit;    /* set the real number of hits */
+  if (ev->ntrack > itrack) ev->ntrack = itrack;    /* set real nr of tracks */
+
+  if (c != EOF) 
+    ungetc(*s, fp->fp);
+
+  ev->nch=rdmc_count_nch(ev);         /* calc the number of hitted channels */
+  ev->nstr=rdmc_count_nstr(ev);      /* calc the number of hitted channels */
+
+  return 0;
+  
+} /* function revt_ascii() */
+
+/****************************************************************************/
+/* function warr_ascii() writes the array info to a dumand-like file        */
+/* This function writes out the head of a DUMAND ascii file                 */
+/* opposite to reading the input file it writes not only                    */
+/* the Geometry banks ('G', 'P') , but also the ('V' and 'M' flags)         */
+/* so the function whd_ascii does not exist                                 */
+/****************************************************************************/
+
+int rdmc_warr_ascii(const mcfile *fp,const array *geo)
+{
+  int iom;                                              /* om index in loop */
+  int itrigger;                                    /* trigger index in loop */
+
+  fprintf(fp->fp, "V %i\n",                             /* write the V flag */
+          DUMAND_ASCII_VERSION);                                /* version number */
+
+  rdmc_wrcomment_ascii(fp,fp->creator);
+  rdmc_wrcomment_ascii(fp,fp->comment);
+  /* write M-line */
+  fprintf(fp->fp,"M %c %s %i %i %i %i %i %i\n"
+         ,fp->info.dum.mc_id
+         ,fp->info.dum.mc_vers
+         ,geo->nrun
+         ,geo->id
+         ,fp->info.dum.igen 
+         ,fp->info.dum.igtrack
+         ,fp->info.dum.daswrun
+         ,rdmc_o_rdateconv(fp->info.dum.time)       /* write the time in YYMMDD format */
+         );
+
+
+  for (itrigger = 0; itrigger < geo->n_trigger; itrigger++) {
+    fprintf(fp->fp, "Q U %s -1 -1 -1. -1.\n",
+           geo->def_trig[itrigger].tag);
+  }
+
+  if (geo->comment != NULL)                 /* if there is a common comment */
+    rdmc_wrcomment_ascii(fp, geo->comment);
+
+  if ((geo->nch>0)||(geo->id > 0)) {     /* if there was a detector geometry */
+    fprintf(fp->fp,"G %i %i %i %.2f %.2f %.1f\n",
+           geo->id,geo->nch,geo->nstr,
+           geo->lattitude, geo->longitude, geo->depth);         /* 'G' flag */
+  }
+/************** write now the positions ('P') of all channels ***************/
+
+  for (iom = 0 ; iom < geo->nch ; iom++) {
+
+    int ori;    /* change orientation from cos theta to 1 for up and 2 down */
+
+    ori = 0;
+    if (geo->costh[iom] > 0.5) ori = 1;  /* up */
+    if (geo->costh[iom] < -0.5) ori = 2; /* down */
+
+    fprintf(fp->fp,"P %i %i %i %i %li %li %li %i %i %f %f\n",
+           iom+1,geo->type[iom],
+           geo->serial[iom],
+           geo->str[iom],
+           rdmc_nint(geo->x[iom] * 1000.),
+           rdmc_nint(geo->y[iom] * 1000.),
+           rdmc_nint(geo->z[iom] * 1000.),
+           ori,
+           geo->clust[iom] + 1,
+           geo->thresh[iom],
+           geo->sensit[iom]);
+  } /* for iom */
+
+/**** write now the calibration ('K') of all channels, if there is one *******/
+
+  for (iom = 0 ; iom < geo->nch ; iom++) {
+    if ( (geo->is_calib.adc)
+        || (geo->is_calib.tdc) ){
+      fprintf(fp->fp,"K %i %.5f %.3f %.3f %.2f %.5f %.2f\n",
+             iom+1,
+             geo->cal[iom].beta_t,
+             geo->cal[iom].t_0,
+             geo->cal[iom].alpha_t,
+             geo->cal[iom].ped,
+             geo->cal[iom].beta_a,
+             geo->cal[iom].kappa);
+    }
+  } /* for iom */
+
+  return 0;
+
+} /* warr_ascii() */
+
+/****************************************************************************/
+/* function wevt_ascii() writes an event to a dumand-like file              */
+/****************************************************************************/
+
+int rdmc_wevt_ascii(const mcfile *fp,const mevt *event, const array *ar)
+{
+  int itra,ifit,ihit;                           /* MC-track looop varialble */
+  int iuser;                                 /* loop over user-def'd fields */
+                                               
+  fprintf(fp->fp,"E %i %i %i %i %i %i %i %li %li %i %s\n", /* the 'E' flag */
+         event->enr,
+         event->nhits,
+         (int)rdmc_mjd_to_unixtime(event->mjd, event->secs),/* the time in secs */
+         event->nsecs,                        /* the nsec part of the time */
+         0,0,0,                             /* dummies for the Dumand time */
+         event->trigger,
+         rdmc_nint(event->t_offset),event->ntrack,"Q1");
+
+  for (itra=0 ; itra<event->ntrack ; itra++)  {  /* write out the 'T' flags */
+    fprintf(fp->fp,"T %i %li %li %li %g %g %g %li %.2f %i %li\n"
+           ,event->gen[itra].tag
+           ,rdmc_nint(event->gen[itra].x * 1000 )
+           ,rdmc_nint(event->gen[itra].y * 1000 )
+           ,rdmc_nint(event->gen[itra].z * 1000 )
+           ,event->gen[itra].px
+           ,event->gen[itra].py
+           ,event->gen[itra].pz
+           ,rdmc_nint( event->gen[itra].e )
+           ,event->gen[itra].t
+           ,event->gen[itra].id
+           ,rdmc_nint(event->gen[itra].length * 1000));
+  }
+
+  for (ihit=0 ; ihit<event->nhits ; ihit++)   {  /* write now the 'H' flags */
+    fprintf(fp->fp,"H %i %i %g %.2f %.2f %s %i"
+           ,event->h[ihit].str
+           ,event->h[ihit].ch+1
+           ,event->h[ihit].tot
+           ,event->h[ihit].amp
+           ,event->h[ihit].t
+           ,"U0"
+           ,event->h[ihit].mt);
+    if (event->h[ihit].ma > 0)
+      fprintf(fp->fp, " %i\n",event->h[ihit].ma);
+    else
+      fprintf(fp->fp, "\n");
+  } /* for ihit */
+
+  for (ifit=0 ; ifit<event->nfit ; ifit++)   {    /*write now the 'F' flags */
+
+    if ( (event->fresult != NULL)              /* if there is an jk record */
+       && (0 <= event->fresult[ifit].id )
+       && (ar->n_fit > event->fresult[ifit].id )  /* there is a fit defined  */
+       && (rdmc_is_this_jk(&(ar->def_fit[event->fresult[ifit].id])
+                              ,&(event->fresult[ifit])) ) ) {
+
+      fprintf(fp->fp
+             ,"F %i %li %li %li %g %g %g %li %.2f %g %g %g %g %g %i %i %li\n"
+             ,(int) rdmc_nint(event->fresult[ifit].val[JK_FITID])
+             ,rdmc_nint(event->rec[ifit].x * 1000. )
+             ,rdmc_nint(event->rec[ifit].y * 1000. )
+             ,rdmc_nint(event->rec[ifit].z * 1000. )
+             ,event->rec[ifit].px
+             ,event->rec[ifit].py
+             ,event->rec[ifit].pz
+             ,rdmc_nint( event->rec[ifit].e )
+             ,event->rec[ifit].t
+             ,event->fresult[ifit].val[JK_RCHI2]
+             ,event->fresult[ifit].val[JK_PROB]
+             ,event->fresult[ifit].val[JK_SIGTH]
+             ,event->fresult[ifit].val[JK_COVMIN]
+             ,event->fresult[ifit].val[JK_COVMAX]
+             ,(int) rdmc_nint(event->fresult[ifit].val[JK_CUTFLAG])
+             ,event->rec[ifit].id
+             ,rdmc_nint(event->rec[ifit].length*1000.));
+    }else{
+      fprintf(fp->fp
+             ,"F %i %li %li %li %g %g %g %li %.2f %g %g %g %g %g %i %i %li\n"
+             ,RDMC_NA
+             ,rdmc_nint(event->rec[ifit].x * 1000. )
+             ,rdmc_nint(event->rec[ifit].y * 1000. )
+             ,rdmc_nint(event->rec[ifit].z * 1000. )
+             ,event->rec[ifit].px
+             ,event->rec[ifit].py
+             ,event->rec[ifit].pz
+             ,rdmc_nint( event->rec[ifit].e )
+             ,event->rec[ifit].t
+             ,(float) RDMC_NA
+             ,(float) RDMC_NA
+             ,(float) RDMC_NA
+             ,(float) RDMC_NA
+             ,(float) RDMC_NA
+             , RDMC_NA
+             ,event->rec[ifit].id
+             ,rdmc_nint(event->rec[ifit].length*1000.));
+    }
+  }
+
+
+  if (event->nuser > 0) {                        /* if there is a user field */
+    int ival;
+    for (iuser = 0; iuser < event->nuser; iuser++) {  /* for all user fields */
+      fprintf(fp->fp, "U");                          /* write the field id */
+      for(ival=0 ; ival < event->user[iuser].nval ; ival++){
+       fprintf(fp->fp," %g",event->user[iuser].val[ival]); /* write the field */
+      }
+      fprintf(fp->fp, "\n");                                   /* end the line */
+    } /* for iuser */
+  } /* if nuser > 0 */
+
+  if (event->comment != NULL)                /* if there is an event comment */
+    rdmc_wrcomment_ascii(fp, event->comment);
+
+  return 0;
+
+} /* function wevt_ascii() */
+
+/****************************************************************************/
+/* wrcomment_ascii() writes a comment line to an ASCII file                 */
+/****************************************************************************/
+
+int rdmc_wrcomment_ascii(const mcfile *fp, const char *s)
+{
+  static char *line=NULL;                  /* temporary copy of the string */
+  char *eol;                                         /* end of current line */
+  char *bol;                                       /* beginning of the line */
+
+
+  if(s){
+#ifndef CRAY
+    line = alloca((strlen(s)+1)*sizeof(char));
+#else
+    line = malloc((strlen(s)+1)*sizeof(char));
+#endif
+    strcpy(line,s);                                       /* copy the string */
+    for (bol = eol = line; eol; bol = eol+1) {              /* for each line */
+      eol = strchr(bol,'\n');                             /* search line end */
+      if (eol) *eol = '\0';                          /* replace it with '\0' */
+      if (*bol != '\0')                          /* if it contains something */
+       fprintf(fp->fp, "C %s\n", bol+1);                  /* print the line */
+    }
+  }
+#ifdef CRAY
+  free(line);   /* Jacobsen added semicolon here */
+#endif
+
+  return 0;
+
+} /* wrcomment_ascii() */
+
+/****************************************************************************/
+/* rhd_ascii() reads the format relevant informations for dumand-like       */
+/*          formats                                                         */
+/****************************************************************************/
+
+int rdmc_rhd_ascii(mcfile *fp) 
+{
+  char s[RDMC_MAXLINE];                                            /* input line */
+  int c;                                                      /* first char */
+
+  do {                                              /* read comment lines */
+    *s = c = getc(fp->fp);
+    if (c == EOF)
+      return EOF;
+    if (toupper((int) *s) != 'C') {
+      ungetc(c, fp->fp);
+      break;
+    }
+    if (fgets(s+1, RDMC_MAXLINE-1, fp->fp) == NULL)
+      return EOF;
+    fp->fpos++;
+  } while (rdmc_a_C(s,&(fp->creator)) == 0);
+
+  *s = c = getc(fp->fp);
+  if (c == EOF)
+    return EOF;
+  if (*s != 'M') {                          /* if there is *not* a 'M' line */
+    ungetc(*s, fp->fp);                            /* ungetch the last char */
+    return 0;
+  } /* if *s != M */
+  
+  
+  if (fgets(s+1,RDMC_MAXLINE-1,fp->fp) == NULL)         /* try to read next line */
+    return EOF;
+  fp->fpos += 1;
+
+  if (rdmc_a_M(s,fp) != 0)                             /* monte carlo infos */
+    return ERRLINE;
+  
+  return 0;
+
+} /* function rhd_ascii() */
+
+/****************************************************************************/
+/* skipevt_ascii() skips the next event from a dumand-like file             */
+/****************************************************************************/
+
+int rdmc_skipevt_ascii(mcfile *fp)
+{
+  char s[RDMC_MAXLINE];                                            /* input line */
+  int c;                                                      /* first char */
+
+  *s = c = getc(fp->fp);                                     /* read a char */
+  if (c == EOF)
+    return EOF;
+
+  fp->fpos += 1;
+  if (fgets(s+1,RDMC_MAXLINE-1,fp->fp) == NULL)        /* try to read first line */
+    return EOF;
+
+  for (*s =c = getc(fp->fp); (*s != 'E') && (c != EOF); *s = c = getc(fp->fp)){
+                                  /* for all lines *not* beginning with 'E' */
+    fp->fpos += 1;
+    if (fgets(s+1,RDMC_MAXLINE-1,fp->fp) == NULL)               /* read the line */
+      return EOF;
+  }
+
+  if (c != EOF)
+    ungetc(*s, fp->fp);
+
+#if 0
+  fp->enr++;                                       /* increase event number */
+#endif
+
+  return 0;
+
+} /* function skipevt_ascii() */
+
+
+/****************************************************************************/
+/* functions for reading the dumand-like files                              */
+/****************************************************************************/
+
+int rdmc_a_V(const char *s, mcfile *fp) /* scans the V card  */
+{ 
+
+  int form = 0;
+
+  if(sscanf(s,"V %i ",&form) != 1) 
+    return ERRLINE;
+  fp->fmajor = form;
+  fp->fminor = 0;
+
+  return 0;
+
+} /* function rdmc_a_V() */
+
+/****************************************************************************/
+
+static int rdmc_a_C(const char *s, char **comment) /* read comment line */
+{ 
+
+  while (*s == ' ') 
+    s++;
+  
+  if (toupper(*s != 'C'))
+    return 1;
+
+  s += 2;
+
+  /*now append it */
+  rdmc_concat_comment(comment,s,DUMAND_ASCII_F);
+
+  return 0;
+
+} /* function rdmc_a_C() */
+
+/****************************************************************************/
+
+static int rdmc_a_G(const char *s, array *ar) /* scans the G line  */
+{ 
+
+  int form;
+
+  form = sscanf(s,"G %i %i %i %f %f %f", 
+               &(ar->id), &(ar->nch), &(ar->nstr), 
+               &(ar->lattitude), &(ar->longitude), &(ar->depth));
+
+  switch(form) {
+  case 0: ar->id = 0;
+  case 1: ar->nch = 0;
+  case 2: ar->nstr = 0;
+  case 3: ar->lattitude = 0.0;
+  case 4: ar->longitude = 0.0;
+  case 5: ar->depth = 0.0;
+  default: break;
+  } /* switch form */
+
+  return 0;
+
+} /* function rdmc_a_G() */
+
+/****************************************************************************/
+
+static int rdmc_a_M(const char *s, mcfile *fp)
+{
+  int form;
+  char id;
+  int irun,igeo,igen,igtrack,daswrun,date;
+  char mc_version[RDMC_MAXLINE];
+
+  if (s[0] != 'M' ) 
+    return -1;
+
+  if( (form = sscanf(s,"M %c %s %i %i %i %i %i %i ",
+       &id,mc_version,&irun,&igeo,&igen,&igtrack,&daswrun,&date) )  != 8) {
+    if (form != 7 ){
+      return ERRLINE;
+    }
+    else {
+      date= 700101;  
+    }
+  }
+  switch (id) {
+  case 'D': /*allowed id's */
+  case 'U':
+  case 'G':
+  case 'M':
+    fp->info.dum.mc_id = id;
+    break;
+  case 'B': /* old data */
+    fp->info.dum.mc_id = 'D';
+    break;
+  case 'J': /* old MC */
+  case 'S':
+    fp->info.dum.mc_id = 'M';
+    break;
+  default: /* unknown */
+    fp->info.dum.mc_id = 'U';
+    break;
+  }
+  strcpy(fp->info.dum.mc_vers,mc_version);
+  fp->info.dum.nrun = irun;
+  fp->info.dum.igen =igen;
+  fp->info.dum.igtrack = igtrack ;
+  fp->info.dum.time = rdmc_o_dateconv(date);
+  fp->info.dum.daswrun = daswrun;
+  switch (fp->info.dum.mc_id) {
+  case 'G':
+    fp->info.dum.igeo =0;
+    fp->info.dum.igtrack =-1;
+    break;
+  case 'D': /* data */
+    fp->info.dum.igtrack =-1;
+    fp->info.dum.igen =0;
+    fp->info.dum.daswrun =-1;
+    break;
+  case 'M':
+    fp->info.dum.igtrack =-1;
+    break;
+  }
+  return 0;
+  
+} /* function rdmc_a_M() */
+
+/****************************************************************************/
+
+static int rdmc_a_P(const char *s, array *ar)
+{
+
+  int form;
+  long ch, type, serial, str,  iclust;
+  float x,y,z;
+  const float cs_ori[3] = {0.0, 1.0, -1.0};
+  float thresh, rsense, ori;
+
+  form = sscanf(s,"P %li %li %li %li %f %f %f %f %li %f %f"
+               ,&ch
+               ,&type
+               ,&serial
+               ,&str
+               ,&x
+               ,&y
+               ,&z
+               ,&ori
+               ,&iclust
+               ,&thresh
+               ,&rsense);
+  if (form == 0) return 0;                         /* not a "P" line, ignore */
+  if ((form <8) || (form >11)) return ERRLINE;
+  ch--;                                     /* I want a 'C' style of indizes */
+  if ((ch < 0) ||(ch >= RDMC_MAXCHANNELS) || (ch >= ar->nch))
+    return ERRLINE;
+
+  ar->str[ch] = str;
+  ar->type[ch] = type;
+  ar->x[ch] = x/1000.0;
+  ar->y[ch] = y/1000.0;
+  ar->z[ch] = z/1000.0;
+  if ((ori < 0) || (ori > 2))
+    return ERRLINE;
+
+  if (form > 8)                             /* if there was an icluster info */
+    ar->clust[ch] = iclust - 1;                 /* fill it as channel number */
+  else                                                /* if no icluster info */
+    ar->clust[ch] = -1;
+
+  ar->costh[ch] = cs_ori[(int)ori];
+  ar->serial[ch] = serial;
+  if (form > 9)
+    ar->thresh[ch] = thresh;
+  else
+    ar->thresh[ch] = RDMC_SMALL;
+  if (form > 10)
+    ar->sensit[ch] = rsense;
+  else
+    ar->sensit[ch] = 1.0;
+
+  /* now set the geo cal flag */
+  ar->is_calib.geo=1;
+  return 0;
+
+} /* function rdmc_a_P() */
+
+/****************************************************************************/
+
+static int rdmc_a_K(const char *s, array *ar)
+{
+
+  int form;
+  array_calib_t cal;
+  int ich;
+
+  
+  form = sscanf(s,"K %i %f %f %f %f %f %f",
+               &ich,
+               &(cal.beta_t), &(cal.t_0), &(cal.alpha_t),
+               &(cal.ped), &(cal.beta_a), &(cal.kappa));
+  switch (form) {
+  case 1: cal.beta_t = 0.0;
+  case 2: cal.t_0 = 0.0;
+  case 3: cal.alpha_t = 0.0;
+  case 4: cal.ped = 0.0;
+  case 5: cal.beta_a = 0.0;
+  case 6: cal.kappa = 0.0;
+  case 7: 
+    cal.flag = RDMC_CALIB_TDC | RDMC_CALIB_ADC ;
+    break;
+  default:
+    return 0;
+  }
+
+  if ((ich > 0) && (ich <= RDMC_MAXCHANNELS))
+    ar->cal[ich-1] = cal;
+
+  /* now set the  cal flag */
+  ar->is_calib.tdc=1;
+  ar->is_calib.adc=1;
+  
+  return 0;
+
+} /* function rdmc_a_K() */
+
+/****************************************************************************/
+
+static int rdmc_a_Q(const char *s, array *ar)
+{
+  int form;
+  array_hdef_t trig;
+  char id;
+
+  rdmc_init_array_hdef(&(trig));
+
+  form = sscanf(s,"Q %c %s %s %s %s %s",
+               &(id), trig.tag
+               , trig.pars[0], trig.pars[1]
+               , trig.pars[2], trig.pars[3] );
+  switch (form) {
+  case 3: 
+  case 4: 
+  case 5: 
+  case 6: 
+  case 2: 
+    break;
+  default:
+    return 0;
+  }
+
+  trig.id  = ar->n_trigger+1;
+  trig.nwords =  0;
+  trig.npars = form -2 ;
+
+  if (ar->n_trigger+1 < RDMC_MAXTRIGID){
+    rdmc_add_trigger_def(ar,&trig,ar->n_trigger);
+  }
+
+  return 0;
+
+} /* function rdmc_a_Q() */
+
+/****************************************************************************/
+
+static int rdmc_a_E(const char *s, mevt *ev)
+{
+
+  char trig[RDMC_MAXLINE];
+  int form; 
+  unsigned long trigger; 
+  int sec;
+  unsigned nsec;
+  unsigned DUMtLSW;                                             /* dummies */
+  int DUMtMSW, rperiodtime;                                      /* dummies */
+
+  form = sscanf(s,"E %i %i %i %u %i %u %i %li %g %i %s ",
+                &(ev->enr),&(ev->nhits),
+                &sec, &nsec, 
+                &DUMtMSW, &DUMtLSW, 
+               &rperiodtime,
+               &(trigger), &(ev->t_offset), &(ev->ntrack),
+                trig);
+  switch( form) {
+  case 2:  sec = 0;
+  case 3:  nsec = 0;
+  case 4:  DUMtMSW = 0;
+  case 5:  DUMtLSW = 0;
+  case 6:  rperiodtime = 0;
+  case 7: trigger = 0;
+  case 8:  ev->t_offset=0.;
+  case 9:  ev->ntrack = 0;
+  case 10: strcpy(trig,"0");
+  case 11:
+    break;
+  default:
+    return ERRLINE;
+    break;
+    }
+
+  if (sec == -1) sec = 0;           /* -1 means: no time was stored */
+  if (DUMtMSW == -1) {DUMtMSW = 0; DUMtLSW = 0; }
+  if (rperiodtime == -1) rperiodtime = 0;
+
+  ev->mjd = rdmc_unixtime_to_mjd(sec);            /* convert unix time into mjd */
+  ev->secs = rdmc_unixtime_to_mjdsecs(sec);           /* and seconds after mjd */
+  ev->nsecs = nsec;
+
+  /* now add the trigger */
+  {
+    mevt_special_t ptrig;
+    int itrig;
+    rdmc_init_mevt_special(&ptrig,0);
+    for (itrig = 0 ; itrig <RDMC_MAXTRIGID ; itrig++){
+      if ( (trigger) & (1  << itrig)){
+       ptrig.id = itrig;
+       rdmc_add_trigger(ev, &ptrig, ev->ntrig, itrig);
+      }
+    }
+  }
+
+
+  return 0;
+  
+} /* function rdmc_a_E() */
+
+/****************************************************************************/
+
+static int rdmc_a_H(const char *s, mhit *h)
+{
+
+  int form;
+  char htrig[RDMC_MAXLINE];
+
+  form = sscanf(s,"H %i %i %g %g %g %s %i %i",
+               &(h->str),&(h->ch),
+               &(h->tot),
+               &(h->amp),
+               &(h->t),
+               htrig,
+               &(h->mt),
+               &(h->ma));
+  switch (form) {
+  case 5:
+    strcpy(htrig, "U0");
+  case 6:
+    h->mt = RDMC_NA;
+  case 7:
+    h->ma = RDMC_NA;
+  case 8:
+    break;
+  default:
+    return ERRLINE;
+  }
+  h->ch--;                        /* for 'c' style of channel number (0,...) */
+#if 0 /* this is stupid */
+  h->mt = abs(h->mt);         /* it's possible to have negative track id's */
+  h->ma = abs(h->ma);         /* it's possible to have negative track id's */
+#endif
+  return 0;
+
+} /* function rdmc_a_H() */
+
+/****************************************************************************/
+
+static int rdmc_a_T(const char *s, mtrack *t)
+{
+
+  int form;
+
+  rdmc_init_mtrack(t); 
+  form  = sscanf(s,"T %i %f %f %f %f %f %f %f %f %i %f "
+                ,&(t->tag)
+                ,&(t->x),&(t->y),&(t->z)
+                ,&(t->px),&(t->py),&(t->pz)
+                ,&(t->e),&(t->t) 
+                ,&(t->id),&(t->length));
+  switch (form)
+    {
+    case 10:
+      t->length = RDMC_NA;
+    case 11:
+      t->length *= 1e-3;       /* dumand format: millimeter, in rdmc: meter */
+      if (t->length < 0.)
+       t->length = RDMC_NA;  /*10. * t->e/100000. ; */
+      t->x *= 1.e-3;
+      t->y *= 1.e-3;
+      t->z *= 1.e-3;
+      rdmc_tauinv_tr(t);                         /* calc cos theta and phi */
+      break;
+    default:
+      return ERRLINE;
+    }
+  
+  return 0;
+
+} /* function rdmc_a_T() */
+
+/****************************************************************************/
+
+static int rdmc_a_F(const char *s, mtrack *t, mevt_special_t *krabi)
+{
+
+  int form;
+
+  form  = sscanf(s,"F %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %i %g"
+                ,&(krabi->val[JK_FITID])
+                ,&(t->x),&(t->y),&(t->z)
+                ,&(t->px),&(t->py),&(t->pz)
+                ,&(t->e)
+                ,&(t->t) 
+                ,&(krabi->val[JK_RCHI2])
+                ,&(krabi->val[JK_PROB])
+                ,&(krabi->val[JK_SIGTH])
+                ,&(krabi->val[JK_COVMIN])
+                ,&(krabi->val[JK_COVMAX])
+                ,&(krabi->val[JK_CUTFLAG])
+                ,&(t->id) 
+                ,&(t->length) );
+
+
+  krabi->val[JK_CHI2]=RDMC_NA;
+  switch (form)   /* minimum 10 maximal 17 */
+    {
+    case 10:
+      krabi->val[JK_PROB] =  RDMC_NA;
+    case 11:
+      krabi->val[JK_SIGTH] = RDMC_NA ;
+    case 12:
+      krabi->val[JK_COVMIN] =  RDMC_NA;
+    case 13:
+      krabi->val[JK_COVMAX] = RDMC_NA ;
+    case 14:
+      krabi->val[JK_CUTFLAG] = RDMC_NA  ;
+    case 15:
+      t->id = MUON_MINUS ;
+    case 16:
+      t->length = RDMC_NA;
+    case 17:
+
+      t->length *= 1e-3;       /* dumand format: millimeter, in rdmc: meter */
+      if (t->length < 0.)
+       t->length = RDMC_NA;  /*10. * t->e/100000. ; */
+      t->x *= 1.e-3;
+      t->y *= 1.e-3;
+      t->z *= 1.e-3;
+      rdmc_tauinv_tr(t);                               /* calc cos theta and phi */
+      break;
+    default:
+      return ERRLINE;
+    }
+  
+  return 0;
+
+} /* function rdmc_a_F() */
+
+/****************************************************************************/
+/* rdmc_a_U() reads optional user fields from a comment line                */
+/*  it reallocates the the user field                                       */
+/****************************************************************************/
+
+static int rdmc_a_U(const char *s, mevt_special_t **user, int *nuser)
+{
+  char *t=NULL;
+  char *tp;
+  mevt_special_t temp_user;
+  int iuser,imod;
+  int i;
+  int r=0;
+
+  if (s[0] != 'U')
+    return 0;
+
+#ifndef CRAY
+  t = alloca(strlen(s)+1);
+#else
+  t = malloc(strlen(s)+1);
+#endif
+  strcpy(t,s);
+  
+  rdmc_init_mevt_special(&temp_user, RDMC_MAXUSER_PER_LINE);
+  
+  /* get number of previous these users */
+  iuser = 0;
+  for (i = 0; i < *nuser; i++){
+    iuser += (*user)[i].nval;
+  }
+  /* iuser is now the index for the new user or the number of previous ones */
+
+  /* now get the last user into temp_user */
+  if (iuser > 0){
+    rdmc_cp_mevt_special(&temp_user, &((*user)[*nuser-1]));
+    r |= rdmc_del_mevt_special(user, nuser, (*nuser)-1);
+    imod = temp_user.nval;
+  }  else {
+    imod = 0;
+    temp_user.id = iuser % DUMAND_USER_MAX;
+  }
+
+  /* now parse the line and add users */
+  for (tp = strtok(t," \t\n"); tp && (iuser < DUMAND_USER_MAX);
+       tp = strtok(NULL," \t\n")) {
+    iuser++;
+    /* check if current user is filled */
+    if (imod >= DUMAND_MAXUSER_PER_LINE) {
+      r |= rdmc_add_mevt_special(user,nuser,&temp_user,*nuser); 
+      rdmc_init_mevt_special(&temp_user,RDMC_MAXUSER_PER_LINE);
+      temp_user.id = iuser%DUMAND_USER_MAX;
+      imod = 0;
+    }
+    /* now fill the values */
+    temp_user.val[imod] = atof(tp);
+    temp_user.nval = imod++;
+  }
+  /* now commit a last uncommitted block */
+  if (iuser > 0) 
+    r |= rdmc_add_mevt_special(user,nuser,&temp_user,*nuser); 
+
+#ifdef CRAY
+  free(t);
+#endif
+  return r;                             /* there should not occure an error */
+
+} /* function rdmc_a_U() */
+
+#if 0
+/****************************************************************************/
+/* a_skip_C() skips all comment lines and points to the next line in ASCII  */
+/****************************************************************************/
+static int a_skip_C(mcfile *fp)
+{
+  
+  int c;
+  char s[RDMC_MAXLINE];
+
+  while ((c = getc(fp->fp)) == 'C'){
+    ungetc(c, fp->fp);
+    fp->fpos += 1;
+    fgets(s, RDMC_MAXLINE-1, fp->fp);
+  }
+
+  if (c == EOF) 
+    return EOF;
+  else {
+    ungetc(c, fp->fp);
+    return 0;
+  }
+
+} /* function a_skip_C() */
+#endif
+
+/****************************************************************************/
+/* declare_rdmc_user() declares a default user tag               */
+/****************************************************************************/
+
+static int  declare_rdmc_dumand_user(array *ar){
+  array_hdef_t dumand_user_def;
+  int i;
+  int r=0;
+  int iblock=0;
+
+  rdmc_init_array_hdef(&dumand_user_def);
+
+  for (i=0 ; i < DUMAND_USER_MAX ;i++){
+    dumand_user_def.nwords++;
+    sprintf(dumand_user_def.words[i%DUMAND_MAXUSER_PER_LINE],"u%i",i+1);
+    if (((i+1)%DUMAND_MAXUSER_PER_LINE)==0){
+      iblock++;
+      dumand_user_def.id=iblock;
+      sprintf(dumand_user_def.tag,"dumand%i",iblock);
+      r |= rdmc_add_user_def(ar, &dumand_user_def, ar->n_user);
+      rdmc_init_array_hdef(&dumand_user_def);
+    }
+  }
+  /* clean up the rest */
+  if (((i+1)%DUMAND_MAXUSER_PER_LINE) !=0 ){
+    iblock++;
+    dumand_user_def.id=iblock;
+    sprintf(dumand_user_def.tag,"dumand%i",iblock);
+    r |= rdmc_add_user_def(ar, &dumand_user_def, ar->n_user);
+  }
+
+  return r;
+}
+
+/****************************************************************************/
+/* parse_fit_def_ascii() parses the creator line for "recoos"               */
+/****************************************************************************/
+
+static int parse_fit_def_ascii(array *ar, const char *s)
+{
+  char *line=NULL;                  /* temporary copy of the string */
+  char *reco;                            /* reco pointer  */
+  char *eol;                                         /* end of current line */
+  char *bol;                                       /* beginning of the line */
+  array_hdef_t dum_fitdef;
+  
+  if(s){
+#ifndef CRAY
+    line = alloca(sizeof(char)*(1+strlen(s)));
+#else
+    line = malloc(sizeof(char)*(1+strlen(s)));
+#endif
+    strcpy(line,s);                                       /* copy the string */
+
+    for (bol = eol = line; eol; bol = eol+1) {              /* for each line */
+      eol = strchr(bol,'\n');                             /* search line end */
+      if (eol) *eol = '\0';                          /* replace it with '\0' */
+      if (*bol != '\0'){                         /* if it contains something */
+       if( (reco=strstr(bol,"recoos (")) != NULL ){ 
+         /* there is a recoos in this history line */ 
+         rdmc_jk_to_fitdef(&(dum_fitdef),ar->n_fit+1);
+         rdmc_add_fit_def(ar,&(dum_fitdef), ar->n_fit);
+       }
+      }
+    }
+#ifdef CRAY
+    free(line);
+#endif
+  }
+  return 0;
+
+} /* parse_fit_def_ascii() */
+
+
+
+#endif /* DUMAND_ASCII_F */
+/****************************************************************************/
+/********************************** E O F ***********************************/
+/****************************************************************************/
+/* 
+   This is just for EMACS:
+   Local Variables:
+   compile-command: "cd .. ; make -k rdmc" 
+   End: 
+*/
diff --git a/RALICE/icepack/iceconvert/dumand.h b/RALICE/icepack/iceconvert/dumand.h
new file mode 100644 (file)
index 0000000..d73944d
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _RDMC_DUMAND_H
+#define _RDMC_DUMAND_H
+
+#include <malloc.h>
+
+int rdmc_a_V(const char *s, mcfile *fp);                     /* ascii lines */
+int rdmc_rhd_ascii(mcfile *fp);           /* reads the format info from the file */
+int rdmc_rarr_ascii(mcfile *fp, array *ar);            /* (dumand/cw ascii file) */
+int rdmc_warr_ascii(const mcfile *fp, const array *ar);        /* (dumand) */
+int rdmc_wrcomment_ascii(const mcfile *fp, const char *s);   /* (dumand) */
+
+int rdmc_revt_ascii(mcfile *fp, mevt *ev, const array *ar); /* (dumand/cw ascii) */
+
+int rdmc_skipevt_ascii(mcfile *fp);                             /* (dumand) */
+
+int rdmc_wevt_ascii(const mcfile *fp, const mevt *ev, const array *ar);
+
+#endif
+
+
diff --git a/RALICE/icepack/iceconvert/f2k.h b/RALICE/icepack/iceconvert/f2k.h
new file mode 100644 (file)
index 0000000..3379c22
--- /dev/null
@@ -0,0 +1,272 @@
+#ifndef _RDMC_F2K_H
+#define _RDMC_F2K_H
+
+#include "rdmc.h"
+
+/******************************************************/
+/* define the posible lines which contribute to f2k */
+/******************************************************/
+#define F2K_MAX_EVENTTYPES 10
+#define F2K_MAX_LINETYPES 100
+
+enum F2K_LINETYPES_T {
+  V_LINE=1  
+  , HI_LINE 
+  , COMMENT_LINE
+  , ARRAY_LINE
+  , FIT_DEF_LINE
+  , STAT_DEF_LINE
+  , USER_DEF_LINE
+  , TRIG_DEF_LINE
+  , TRIG_PAR_LINE
+  , KH_LINE
+  , OM_LINE
+  , KADC_LINE
+  , KTOT_LINE
+  , KTDC_LINE
+  , KUTC_LINE
+  , TBEGIN_LINE
+  , EM_LINE
+  , US_LINE
+  , HT_LINE
+  , WF_LINE
+  , CH_LINE
+  , TR_LINE
+  , FIT_LINE
+  , FRESULT_LINE
+  , TRIG_LINE
+  , STATUS_LINE
+  , USES_LINE
+  , EE_LINE
+  , TEND_LINE
+  , END_LINE
+  , DUMMY_LINE
+};
+
+enum F2K_TAG_SEARCH_T {COMP_STRINGWISE=1, /* stringwise comp */
+                      COMP_STRINGWISE_NOTRAIL,
+                      COMP_CHARWISE, /* one char should fit */
+                      COMP_CHARPUNCT /* same, char is isspunct -> speed */ 
+#if 0
+                      ,COMP_NOTHING /* do not compare at all ->always true */ 
+#endif
+};
+
+
+/************** functions to actually parse the lines ****/
+
+
+typedef int (f2k_parser_fun_t)(mcfile *fp, array *a, 
+                              mevt *e, void *misc);
+/* the void pointer misc is a trick to pass anny target to fill */
+
+typedef struct  { 
+  char tag[RDMC_MAXTOKENLENGTH]; 
+  enum F2K_LINETYPES_T line_id;
+  enum F2K_TAG_SEARCH_T searchtype;
+  f2k_parser_fun_t *parser;
+} f2000_line_t;
+
+/******************************************************/
+/*** Definitions of f2k blocks                     ***/
+/******************************************************/
+
+typedef int (f2k_event_reader_fun_t)(mcfile *fp, array *a, mevt *e);
+typedef int (f2k_event_writer_fun_t)(const mcfile *fp, const array *a, const mevt *e);
+
+typedef struct{
+  enum RDMC_EVENT_T id;
+   const  f2000_line_t *opener[F2K_MAX_LINETYPES];/* lines that are required to indicate such an event */
+  const  f2000_line_t *inner[F2K_MAX_LINETYPES]; /* lines that re alowd within such n event */
+  const  f2000_line_t *closer[F2K_MAX_LINETYPES];/* lines that define the end of such an event */
+  f2k_event_reader_fun_t *reader;
+  f2k_event_writer_fun_t *writer;
+} f2000_event_t;
+
+
+/******************************************************/
+/**** buffer for decoding f2k ************************/
+/******************************************************/
+#define F2K_BUFFERSIZE 32768 /* initial size of the raw text buffer */
+#define F2K_LINE_BUFFERSIZE 2048 /* initial size of the raw text buffer */
+
+
+
+typedef struct rdmc_f2k_buffer_s { /* a structure to keep track of raw lines */
+  unsigned long int used; /*length of the buffer (excluding last \0) */
+  unsigned long int ntot;   /* number of allocated chars in buff */ 
+  char *buff;             /* this buffers the raw text  */
+  /* now the decoding of the lines */
+  unsigned long int lines;   /* number of gathered lines in buff */ 
+  unsigned long int lines_tot;   /* number of allocated lines in buff */ 
+  unsigned long int iline;    /* the current line under investigation */
+  const f2000_line_t **type_def;  /* pointer to the global array definition */
+  char **line_pt;               /* pointer to each line in buffer */
+} rdmc_f2k_buffer_t; 
+/* the last element of line_pt is always set to NULL */
+
+
+/* **************************************************** */
+/* now this are all known event functions  */
+/* *****************************************************/
+
+// the different formats differe only in the events
+extern const f2000_event_t f2000_preamble_1x1; /* works for 1.1, 1.2, 2004.1*/
+extern const f2000_event_t f2000_mhead_1x1; /* works for 1.1, 1.2, 2004.1*/
+extern const f2000_event_t f2000_mfoot_1x1;
+
+extern const f2000_event_t *f2000_events_1x1[];
+extern const f2000_event_t *f2000_events_1x2[];
+extern const f2000_event_t *f2000_events_2004x1[];
+
+
+/* ******************************************************************* */
+/* Functions in f2k_utl.c */
+/* ******************************************************************* */
+
+
+
+/* functions that convert special strings to rdmc values and vice versa */
+f2k_parser_fun_t rdmc_f2k_dummy_parser;
+f2k_event_writer_fun_t rdmc_f2k_dummy_event_writer;
+
+void rdmc_push_f2k_buffer(rdmc_f2k_buffer_t *b, char *s, const f2000_line_t * type_def);
+void rdmc_init_f2k_buffer(rdmc_f2k_buffer_t *b);
+void rdmc_reset_f2k_buffer(rdmc_f2k_buffer_t *b);
+void rdmc_unlink_f2k_buffer(rdmc_f2k_buffer_t *b);
+void rdmc_clear_f2k_buffer(rdmc_f2k_buffer_t *b);
+
+char ** rdmc_f2k_tokenize(char *line, int *nargs);
+
+/* stores specific error information int f2k file pointer for print */
+void rdmc_f2k_errorlog(mcfile *fp);
+
+/* parser routines to catch ?, *, N, NaN, -inf, +inf, na */
+int rdmc_amanda_strtoi(const char *str, int default_nan);
+double rdmc_amanda_strtof(char *str, double default_nan);
+char * rdmc_amanda_itostr(int val, int default_nan);
+char * rdmc_amanda_ftostr(double val, double default_nan);
+
+/* parser to catch some non float values in special blocks */
+double rdmc_amanda_sptof(char *str);
+
+/* parses the status flags at the end of the HT line */
+int rdmc_amanda_mhit_stat(mhit_stat_t *hstat,char *stat_s);
+
+/* return the rdmc value for "up" and "dn" .. and vice versa */
+float rdmc_amanda_fori(char *ori);
+char * rdmc_amanda_sori(float ori);
+
+/* en/decode the time in a sec.ns fomat */
+int rdmc_amanda_strtimetoi(const char *stime, int *sec, int *nsec); /* returns 0 on succes */
+char * rdmc_amanda_itimetostr(int sec, int nsec);
+
+/* create a string the USES lines for itoken */
+char * rdmc_amanda_uses_to_str(int n_uses, mevt_uses_t *uses, int id);
+
+/* tries to patches any year to avoid y2k problems returns corrected year */
+int rdmc_f2k_y2k(int year);
+/* ******************************************************************* */
+/* ******************************************************************* */
+/* Functions in f2k_YxZ.c */
+
+
+f2k_event_reader_fun_t rdmc_rhd_f2k_1x1;
+f2k_event_reader_fun_t rdmc_mhead_f2k_1x1;
+f2k_event_reader_fun_t rdmc_mevt_f2k_1x1;
+f2k_event_reader_fun_t rdmc_mfoot_f2k_1x1;
+
+
+f2k_parser_fun_t  rdmc_amanda_HI_1x1;
+f2k_parser_fun_t  rdmc_amanda_ARRAY_1x1;
+f2k_parser_fun_t  rdmc_amanda_FIT_DEF_1x1;
+f2k_parser_fun_t  rdmc_amanda_STAT_DEF_1x1;
+f2k_parser_fun_t  rdmc_amanda_USER_DEF_1x1;
+f2k_parser_fun_t  rdmc_amanda_TRIG_DEF_1x1;
+f2k_parser_fun_t  rdmc_amanda_TRIG_PAR_1x1;
+f2k_parser_fun_t  rdmc_amanda_OM_1x1;
+f2k_parser_fun_t  rdmc_amanda_KH_1x1;
+f2k_parser_fun_t  rdmc_amanda_KADC_1x1;
+f2k_parser_fun_t  rdmc_amanda_KTDC_1x1;
+f2k_parser_fun_t  rdmc_amanda_KTOT_1x1;
+f2k_parser_fun_t  rdmc_amanda_KUTC_1x1;
+f2k_parser_fun_t  rdmc_amanda_TBEGIN_1x1;
+f2k_parser_fun_t  rdmc_amanda_EM_1x1;
+f2k_parser_fun_t  rdmc_amanda_TR_1x1;
+f2k_parser_fun_t  rdmc_amanda_CH_1x1;
+f2k_parser_fun_t  rdmc_amanda_HT_1x1;
+f2k_parser_fun_t  rdmc_amanda_US_1x1;
+f2k_parser_fun_t  rdmc_amanda_STATUS_1x1;
+f2k_parser_fun_t  rdmc_amanda_trigblock_1x1;
+f2k_parser_fun_t  rdmc_amanda_TRIG_1x1;
+f2k_parser_fun_t  rdmc_amanda_fitblock_1x1;
+f2k_parser_fun_t  rdmc_amanda_FIT_1x1;
+f2k_parser_fun_t  rdmc_amanda_FRESULT_1x1;
+f2k_parser_fun_t  rdmc_amanda_USES_1x1;
+
+f2k_parser_fun_t  rdmc_amanda_HT_1x2;
+f2k_parser_fun_t  rdmc_amanda_WF_1x2;
+
+f2k_parser_fun_t  rdmc_amanda_WF_2004x1;
+
+/* ******************************************************************* */
+/* write functions */
+/* ******************************************************************* */
+/* Functions in f2k_YxZ.c */
+
+
+/* functions handle all writing of 1.1 and 1.2 and 2004.1 */
+f2k_event_writer_fun_t rdmc_whead_f2k_1x1_2;
+f2k_event_writer_fun_t rdmc_wfoot_f2k_1x1_2;
+f2k_event_writer_fun_t rdmc_wevt_f2k_1x1_2;
+
+int rdmc_wrhist_f2k_1x1(const mcfile *fp, const char *s, const char *pre);
+int rdmc_wrcomment_f2k_1x1(const mcfile *fp, const char *s);
+
+
+/* ******************************************************************* */
+/* Line defs  */
+/* ******************************************************************* */
+
+extern const f2000_line_t V_line_1x1; 
+extern const f2000_line_t COMMENT_line_1x1; 
+extern const f2000_line_t HI_line_1x1; 
+extern const f2000_line_t ARRAY_line_1x1; 
+extern const f2000_line_t TRIG_DEF_line_1x1; 
+extern const f2000_line_t TRIG_PAR_line_1x1; 
+extern const f2000_line_t FIT_DEF_line_1x1; 
+extern const f2000_line_t STAT_DEF_line_1x1; 
+extern const f2000_line_t USER_DEF_line_1x1; 
+extern const f2000_line_t KH_line_1x1; 
+extern const f2000_line_t OM_line_1x1; 
+extern const f2000_line_t KADC_line_1x1; 
+extern const f2000_line_t KTDC_line_1x1; 
+extern const f2000_line_t KTOT_line_1x1; 
+extern const f2000_line_t KUTC_line_1x1; 
+extern const f2000_line_t TBEGIN_line_1x1; 
+extern const f2000_line_t EM_line_1x1; 
+extern const f2000_line_t TR_line_1x1; 
+extern const f2000_line_t CH_line_1x1; 
+extern const f2000_line_t HT_line_1x1; 
+extern const f2000_line_t US_line_1x1; 
+extern const f2000_line_t STATUS_line_1x1; 
+extern const f2000_line_t FIT_block_1x1; 
+extern const f2000_line_t TRIG_block_1x1; 
+extern const f2000_line_t TRIG_line_1x1; 
+extern const f2000_line_t FIT_line_1x1; 
+extern const f2000_line_t FRESULT_line_1x1; 
+extern const f2000_line_t USES_line_1x1; 
+extern const f2000_line_t EE_line_1x1; 
+extern const f2000_line_t TEND_line_1x1; 
+extern const f2000_line_t END_line_1x1; 
+
+extern const f2000_line_t HT_line_1x2; 
+extern const f2000_line_t WF_line_1x2; 
+
+extern const f2000_line_t WF_line_2004x1; 
+
+#endif
+
+
+
diff --git a/RALICE/icepack/iceconvert/f2k_1x1.c b/RALICE/icepack/iceconvert/f2k_1x1.c
new file mode 100644 (file)
index 0000000..cc14330
--- /dev/null
@@ -0,0 +1,1944 @@
+
+/* implement functions special for the f2k 1.1 format */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+
+#include "rdmc.h"
+#include "amanda.h"
+#include "f2k.h"
+
+#define USE_TOT_CAL 1 /* this is defined in 1.3 but rdmc always used it in 1.1 already */
+
+#if 0
+#define ATOI(X) strtol(X, (char **)NULL, 10);
+#endif
+#define SEC_PER_DAY 86400
+
+  /* this block defines a uses structuere which is hirachically
+     build by uses elements ... only n amanda.c so far */
+typedef struct {
+  mevt_uses_t *u;
+  int nu;
+  int id;
+} mevt_usesblock_t;
+
+static void rdmc_init_usesblock(mevt_usesblock_t *ub){
+  ub->u=NULL;
+  ub->nu=0;
+  ub->id=0;
+}
+static void rdmc_clear_usesblock(mevt_usesblock_t *ub){
+  if(ub->u)
+    free(ub->u);
+  rdmc_init_usesblock(ub);
+}
+
+const f2000_line_t V_line_1x1 = 
+  {"V " , V_LINE , COMP_STRINGWISE , rdmc_f2k_dummy_parser };
+const f2000_line_t COMMENT_line_1x1 = 
+  {"*!/$%&(][?~+-_:,;@|<>^#\"\\", COMMENT_LINE,COMP_CHARPUNCT,rdmc_f2k_dummy_parser };
+const f2000_line_t HI_line_1x1 = 
+  {"HI ", HI_LINE, COMP_STRINGWISE, rdmc_amanda_HI_1x1 };
+const f2000_line_t ARRAY_line_1x1 = 
+  {"ARRAY ", ARRAY_LINE, COMP_STRINGWISE, rdmc_amanda_ARRAY_1x1 };
+const f2000_line_t TRIG_DEF_line_1x1 = 
+  {"TRIG_DEF ", TRIG_DEF_LINE, COMP_STRINGWISE, rdmc_amanda_TRIG_DEF_1x1 };
+const f2000_line_t TRIG_PAR_line_1x1 = 
+  {"TRIG_PAR ", TRIG_PAR_LINE, COMP_STRINGWISE, rdmc_amanda_TRIG_PAR_1x1 };
+const f2000_line_t FIT_DEF_line_1x1 = 
+  {"FIT_DEF " , FIT_DEF_LINE , COMP_STRINGWISE, rdmc_amanda_FIT_DEF_1x1 };
+const f2000_line_t STAT_DEF_line_1x1 = 
+  {"STAT_DEF ", STAT_DEF_LINE, COMP_STRINGWISE, rdmc_amanda_STAT_DEF_1x1 };
+const f2000_line_t USER_DEF_line_1x1 = 
+  {"USER_DEF ", USER_DEF_LINE, COMP_STRINGWISE, rdmc_amanda_USER_DEF_1x1 };
+const f2000_line_t KH_line_1x1 = 
+  {"KH ", KH_LINE, COMP_STRINGWISE, rdmc_amanda_KH_1x1 };
+const f2000_line_t OM_line_1x1 = 
+  {"OM ", OM_LINE, COMP_STRINGWISE, rdmc_amanda_OM_1x1 };
+const f2000_line_t KADC_line_1x1 = 
+  {"KADC ", KADC_LINE, COMP_STRINGWISE, rdmc_amanda_KADC_1x1 };
+const f2000_line_t KTDC_line_1x1 = 
+  {"KTDC ", KTDC_LINE, COMP_STRINGWISE, rdmc_amanda_KTDC_1x1 };
+const f2000_line_t KTOT_line_1x1 = 
+  {"KTOT ", KTOT_LINE, COMP_STRINGWISE, rdmc_amanda_KTOT_1x1 };
+const f2000_line_t KUTC_line_1x1 = 
+  {"KUTC ", KUTC_LINE, COMP_STRINGWISE, rdmc_amanda_KUTC_1x1 };
+const f2000_line_t TBEGIN_line_1x1 = 
+  {"TBEGIN ", TBEGIN_LINE, COMP_STRINGWISE, rdmc_amanda_TBEGIN_1x1 };
+const f2000_line_t EM_line_1x1 = 
+  {"EM ", EM_LINE , COMP_STRINGWISE, rdmc_amanda_EM_1x1 };
+const f2000_line_t TR_line_1x1 = 
+  {"TR ", TR_LINE, COMP_STRINGWISE, rdmc_amanda_TR_1x1 };
+const f2000_line_t CH_line_1x1 = 
+  {"CH ", CH_LINE, COMP_STRINGWISE, rdmc_amanda_CH_1x1 };
+const f2000_line_t HT_line_1x1 = 
+  {"HT ", HT_LINE, COMP_STRINGWISE, rdmc_amanda_HT_1x1 };
+const f2000_line_t US_line_1x1 = 
+  {"US ", US_LINE, COMP_STRINGWISE, rdmc_amanda_US_1x1 };
+const f2000_line_t STATUS_line_1x1 = 
+  {"STATUS " , STATUS_LINE , COMP_STRINGWISE, rdmc_amanda_STATUS_1x1 };
+const f2000_line_t FIT_block_1x1 = 
+  {"FIT ", FIT_LINE , COMP_STRINGWISE, rdmc_amanda_fitblock_1x1 };
+const f2000_line_t TRIG_block_1x1 = 
+  {"TRIG ", TRIG_LINE, COMP_STRINGWISE, rdmc_amanda_trigblock_1x1 };
+const f2000_line_t TRIG_line_1x1 = 
+  {"TRIG ", TRIG_LINE , COMP_STRINGWISE, rdmc_amanda_TRIG_1x1 };
+const f2000_line_t FIT_line_1x1 = 
+  {"FIT ", FIT_LINE, COMP_STRINGWISE, rdmc_amanda_FIT_1x1 };
+const f2000_line_t FRESULT_line_1x1 = 
+  {"FRESULT " , FRESULT_LINE, COMP_STRINGWISE, rdmc_amanda_FRESULT_1x1 };
+const f2000_line_t USES_line_1x1 = 
+  {"USES ", USES_LINE, COMP_STRINGWISE, rdmc_amanda_USES_1x1 };
+const f2000_line_t EE_line_1x1 = 
+  {"EE", EE_LINE, COMP_STRINGWISE_NOTRAIL, rdmc_f2k_dummy_parser };
+const f2000_line_t TEND_line_1x1 = 
+  {"TEND ", TEND_LINE, COMP_STRINGWISE, rdmc_f2k_dummy_parser };
+const f2000_line_t END_line_1x1 = 
+  {"END", END_LINE, COMP_STRINGWISE_NOTRAIL, rdmc_f2k_dummy_parser };
+/* this line is needed because a 1.1 header may be empty */
+#if 0
+const f2000_line_t DUMMY_line_1x1 = 
+  {"", DUMMY_LINE, COMP_NOTHING, rdmc_f2k_dummy_parser };
+#endif
+
+const f2000_event_t f2000_preamble_1x1 =
+{ RDMC_EVENT_HEADER_PREF,
+  {&(V_line_1x1),NULL},
+  {&(HI_line_1x1) , &(COMMENT_line_1x1),  NULL},
+  {NULL},
+  rdmc_rhd_f2k_1x1, 
+  rdmc_f2k_dummy_event_writer
+};
+
+const f2000_event_t f2000_mhead_1x1 =
+{ RDMC_EVENT_HEADER,
+  {    NULL  },
+  { &(ARRAY_line_1x1),&(KH_line_1x1),&(FIT_DEF_line_1x1),&(TRIG_DEF_line_1x1)
+   ,&(TRIG_PAR_line_1x1),&(STAT_DEF_line_1x1),&(USER_DEF_line_1x1)
+   ,&(KADC_line_1x1),&(KTDC_line_1x1),&(KTOT_line_1x1),&(KUTC_line_1x1)
+   ,&(OM_line_1x1),&(COMMENT_line_1x1),&(TBEGIN_line_1x1)
+   , NULL
+  },
+  {NULL},
+  rdmc_mhead_f2k_1x1,
+  rdmc_whead_f2k_1x1_2
+};
+
+
+const f2000_event_t f2000_mevt_1x1 =
+{ RDMC_EVENT_MUON,
+  { &(EM_line_1x1),
+    NULL
+  },
+  {
+    &(TR_line_1x1),
+    &(HT_line_1x1),  &(CH_line_1x1),    
+    &(STATUS_line_1x1),   &(US_line_1x1),
+    &(FIT_block_1x1),  &(FRESULT_line_1x1),
+    &(TRIG_block_1x1), &(USES_line_1x1),
+    &(COMMENT_line_1x1)
+    ,  NULL
+  },
+  { &(EE_line_1x1)
+    , NULL},
+  rdmc_mevt_f2k_1x1,
+  rdmc_wevt_f2k_1x1_2
+};
+
+const f2000_event_t f2000_mfoot_1x1 =
+{ RDMC_EVENT_FOOT,
+  { &(TEND_line_1x1),
+    NULL
+  },
+  {    &(COMMENT_line_1x1)
+    ,  NULL
+  },
+  { &(END_line_1x1)
+    , NULL},
+  rdmc_mfoot_f2k_1x1,
+  rdmc_wfoot_f2k_1x1_2
+};
+
+const f2000_event_t  * f2000_events_1x1[] 
+  = { 
+    &f2000_mevt_1x1,
+    NULL 
+  };
+
+
+/****************************************************************************
+ * rhd_amanda() reads the format relevant informations for amanda-like
+ *          formats - just the Comments and history lines. 
+ ****************************************************************************/
+int rdmc_rhd_f2k_1x1(mcfile *fp, array *a, mevt *e){
+  int r=RDMC_IO_OK;
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  while( f2k_buff->iline <   f2k_buff->lines ){
+    switch(f2k_buff->type_def[f2k_buff->iline]->line_id){
+    case COMMENT_LINE:
+      rdmc_append_comment(&(fp->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    default: /* HI line, v-line is dummy */
+      r=f2k_buff->type_def[f2k_buff->iline]->parser(fp,a,e,NULL);
+      break;
+    }
+    if(r != RDMC_IO_OK){
+      rdmc_f2k_errorlog(fp);
+      return r;
+    }
+    f2k_buff->iline++;
+  }
+  return r;
+  
+} /* function rhd_amanda() */
+
+
+/****************************************************************************
+ * The function mhead reads the header of a amanda like file
+ ****************************************************************************/
+int rdmc_mhead_f2k_1x1(mcfile *fp, array *ar, mevt *e){
+  int ret=RDMC_IO_OK;  /* the return value */
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+
+  rdmc_init_array(ar);                           /* reset the array */
+
+  while (f2k_buff->iline < f2k_buff->lines){
+    switch(f2k_buff->type_def[f2k_buff->iline]->line_id){
+    case COMMENT_LINE:
+      rdmc_append_comment(&(ar->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    default: /* any other line */
+      ret = f2k_buff->type_def[f2k_buff->iline]->parser(fp,ar,e,NULL);
+      break;
+    }
+    if(ret != RDMC_IO_OK){
+      rdmc_f2k_errorlog(fp);
+      return ret;
+    }
+    f2k_buff->iline++;
+  }
+  return ret;
+} /* function rhd_amanda() */
+
+/****************************************************************************
+ * The function mhead reads the header of a amanda like file
+ ****************************************************************************/
+int rdmc_mevt_f2k_1x1(mcfile *fp, array *ar, mevt *e){
+  int ret=RDMC_IO_OK;  /* the return value */
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+
+  /*************************************************/
+  while (f2k_buff->iline < f2k_buff->lines){
+    switch(f2k_buff->type_def[f2k_buff->iline]->line_id){
+    case COMMENT_LINE:
+      rdmc_append_comment(&(e->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    case EE_LINE:
+      e->ee = 1;
+      ret = RDMC_IO_OK;
+      break;
+    default: /* any other line */
+      ret = f2k_buff->type_def[f2k_buff->iline]->parser(fp,ar,e,NULL);
+      break;
+    }
+    if(ret != RDMC_IO_OK){
+      rdmc_f2k_errorlog(fp);
+      return ret;
+    }
+    f2k_buff->iline++;
+  }
+  e->nch=rdmc_count_nch(e);         /* calc the number of hit channels */
+  rdmc_fill_mhit_str(e,ar);
+  e->nstr = rdmc_count_nstr(e);
+  if (fp->sloppy)
+    rdmc_repair_mhit_id(e);
+
+  return ret;
+} /* function revt_amanda() */
+
+
+/****************************************************************************
+ * The function mhead reads the header of a amanda like file
+ ****************************************************************************/
+int rdmc_mfoot_f2k_1x1(mcfile *fp, array *ar, mevt *e){
+  int ret=RDMC_IO_OK;  /* the return value */
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+
+  /*************************************************/
+
+  while (f2k_buff->iline < f2k_buff->lines){
+    switch(f2k_buff->type_def[f2k_buff->iline]->line_id){
+    case COMMENT_LINE:
+      rdmc_append_comment(&(e->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    default: /* any other line */
+      ret = f2k_buff->type_def[f2k_buff->iline]->parser(fp,ar,e,NULL);
+      break;
+    }
+    if(ret != RDMC_IO_OK){
+      rdmc_f2k_errorlog(fp);
+      return ret;
+    }
+    f2k_buff->iline++;
+  }
+  return ret;
+} /* function revt_amanda() */
+
+
+
+/****************************************************************************
+ * Read a history line
+ ****************************************************************************/
+int rdmc_amanda_HI_1x1( mcfile *fp , array *a, 
+                              mevt *e, void *tmp)
+{
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char *p=s+strlen("HI ");
+
+  /* now append it */
+  if (*p == '\0')  /* nothing there, -> add a '\n' */
+    rdmc_append_comment(&(fp->creator),"\n");
+  else
+    rdmc_append_comment(&(fp->creator),p);
+
+  return RDMC_IO_OK;
+
+} /* rdmc_amanda_HI() */
+
+
+/****************************************************************************
+ * read the various lines
+ ***************************************************************************/
+
+int rdmc_amanda_ARRAY_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if (nargs != 7) return RDMC_ILF;
+
+  /* arg[0] is the token */
+  a->id = rdmc_amanda_idet(args[1]);
+  a->longitude = rdmc_amanda_strtof(args[2],RDMC_LONGI_NA);
+  a->lattitude = rdmc_amanda_strtof(args[3],RDMC_LATTI_NA);
+  a->depth = rdmc_amanda_strtof(args[4],RDMC_DEPTH_NA);
+  a->nstr =  rdmc_amanda_strtoi(args[5],RDMC_NA);
+  a->nch =   rdmc_amanda_strtoi(args[6],RDMC_NA);
+
+  if (a->nch > RDMC_MAXCHANNELS)
+    return RDMC_TOO_MANY_CHANNELS;
+
+  a->is_calib.geo=1; /* set geo cal flag */
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_ARRAY() */
+
+int rdmc_amanda_TRIG_DEF_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  array_hdef_t def_trig;
+  int i;
+  int i_trigger;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 3) return RDMC_ILF;
+  
+  rdmc_init_array_hdef(&def_trig);
+
+  /* now check if this id is existing r */
+  i_trigger = rdmc_get_hdef_tag(a->def_trig, a->n_trigger,args[2] );
+  if (i_trigger >= 0)                      /* this is not unique */
+    return RDMC_INCONSISTENT_GEOMETRY;
+
+
+  def_trig.id = atoi(args[1]) ;
+  strcpy(def_trig.tag,args[2] );
+  
+  if ( (def_trig.nwords = nargs - 3) >  RDMC_MAXTOKEN_PER_LINE)
+    return RDMC_LINE_NOT_PARSED;
+
+  for (i=0 ; i < def_trig.nwords ; i++){
+    strcpy(def_trig.words[i],args[i+3]);
+  }
+  rdmc_add_trigger_def(a,&def_trig,a->n_trigger);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_TRIG_DEF() */
+
+int rdmc_amanda_TRIG_PAR_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0,npars;
+  int i,i_trigger;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 2) return RDMC_ILF;
+  
+  /* now check if this id is existing r */
+  i_trigger = rdmc_get_hdef_tag(a->def_trig, a->n_trigger,args[1] );
+  if (i_trigger < 0)
+    return RDMC_INCONSISTENT_GEOMETRY;
+
+  if (a->def_trig[i_trigger].npars > 0)
+    return RDMC_INCONSISTENT_GEOMETRY;
+  else
+    npars = nargs - 2; 
+  
+  if (npars  >  RDMC_MAXTOKEN_PER_LINE){
+    return RDMC_LINE_NOT_PARSED;
+  }
+
+  a->def_trig[i_trigger].npars=npars;
+
+  for (i=0 ; i < npars ; i++){
+    strcpy(a->def_trig[i_trigger].pars[i],args[i+2]);
+  }
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_TRIG_PAR() */
+
+
+int rdmc_amanda_FIT_DEF_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  array_hdef_t def_fit;
+  int i;
+  int i_fit;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 3) return RDMC_ILF;
+  
+  rdmc_init_array_hdef(&def_fit);
+
+  def_fit.id = atoi(args[1]) ;
+  strcpy(def_fit.tag,args[2] );
+
+  /* now check if this id is existing r */
+  i_fit = rdmc_get_hdef_id(a->def_fit, a->n_fit, def_fit.id );
+  if (i_fit >= 0)                      /* this is not unique */
+    return RDMC_INCONSISTENT_GEOMETRY;
+  
+  if ( (def_fit.nwords = nargs - 3) >  RDMC_MAXTOKEN_PER_LINE)
+    return RDMC_LINE_NOT_PARSED;
+
+  for (i=0 ; i < def_fit.nwords ; i++){
+    strcpy(def_fit.words[i],args[i+3]);
+  }
+  rdmc_add_fit_def(a,&def_fit,a->n_fit);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_FIT_DEF() */
+
+int rdmc_amanda_STAT_DEF_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  array_hdef_t def_stat;
+  int i;
+  int i_stat;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + tag + token arguments */
+  if (nargs < 2) return RDMC_ILF;
+  
+  rdmc_init_array_hdef(&def_stat);
+
+  def_stat.id = a->n_stat;
+  strcpy(def_stat.tag,args[1] );
+
+  /* now check if this id is existing r */
+  i_stat = rdmc_get_hdef_id(a->def_stat, a->n_stat, def_stat.id );
+  if (i_stat >= 0)                      /* this is not unique */
+    return RDMC_INCONSISTENT_GEOMETRY;
+  
+  if ( (def_stat.nwords = nargs - 2) >  RDMC_MAXTOKEN_PER_LINE)
+    return RDMC_LINE_NOT_PARSED;
+
+  for (i=0 ; i < def_stat.nwords ; i++){
+    strcpy(def_stat.words[i],args[i+2]);
+  }
+  rdmc_add_stat_def(a,&def_stat,a->n_stat);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_STAT_DEF() */
+
+
+int rdmc_amanda_USER_DEF_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  array_hdef_t def_user;
+  int i;
+  int i_user;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 2) return RDMC_ILF;
+  
+  rdmc_init_array_hdef(&def_user);
+
+  strcpy(def_user.tag,args[1] );
+
+  /* now check if this id is existing r */
+  i_user = rdmc_get_hdef_tag(a->def_user, a->n_user, def_user.tag );
+  if (i_user >= 0)                      /* this is not unique */
+    return RDMC_INCONSISTENT_GEOMETRY;
+  
+  if ( (def_user.nwords = nargs - 2) >  RDMC_MAXTOKEN_PER_LINE)
+    return RDMC_LINE_NOT_PARSED;
+
+  for (i=0 ; i < def_user.nwords ; i++){
+    strcpy(def_user.words[i],args[i+2]);
+  }
+  rdmc_add_user_def(a,&def_user,a->n_user);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_USER_DEF() */
+
+int rdmc_amanda_KH_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int i;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 1) return RDMC_ILF;
+
+  for (i = 1 ; i < nargs ; i++ ){
+    if ( !strcmp(args[i],"ADC")  ){
+      a->is_calib.adc=1;
+    }
+    else if ( !strcmp(args[i],"TDC")  ){
+      a->is_calib.tdc=1;
+    }
+    else if ( !strcmp(args[i],"UTC")  ){
+      a->is_calib.utc=1;
+    }
+#if 1 /* this is not part of f2000 1.1 but who cares */
+    else  if ( !strcmp(args[i],"TOT")  ){
+      a->is_calib.tot=1;
+    }
+#endif    
+    else   { 
+      if (!(fp->sloppy)) /* no sloppy mode -> return with error */
+       return RDMC_LINE_NOT_PARSED;
+      else
+       continue;
+    }
+  } /* for */
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_KH() */
+
+
+int rdmc_amanda_OM_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int nr;
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs < 8) return RDMC_ILF;
+
+  nr = atoi(args[1]) - 1;
+  if ((nr < 0) || (nr >= a->nch)) return RDMC_INCONSISTENT_GEOMETRY;
+  if ( ( a->str[nr] = atoi(args[3])) > a->nstr)
+    return RDMC_INCONSISTENT_GEOMETRY;
+  a->clust[nr] = atoi(args[2]) - 1;
+  if (isnan(a->x[nr] = atof(args[4]))) return RDMC_ILF;
+  if (isnan(a->y[nr] = atof(args[5]))) return RDMC_ILF;
+  if (isnan(a->z[nr] = atof(args[6]))) return RDMC_ILF;
+  a->costh[nr] = rdmc_amanda_fori(args[7]);
+  a->type[nr]  = rdmc_amanda_iomid(
+                                   (nargs > 8) ? args[8] : "unknown" 
+                                   ,a->id);
+  a->serial[nr] = rdmc_amanda_strtoi(
+                                    (nargs > 9) ? args[9] : "na"
+                                    ,RDMC_NA);
+  a->sensit[nr] = rdmc_amanda_strtof(
+                                    (nargs > 10) ? args[10] : "1.0"
+                                    , 1.0);
+
+  if( nargs > 11 ) 
+    a->thresh[nr] = rdmc_amanda_strtof(args[11],RDMC_SMALL);
+  else{
+    char tmp[RDMC_MAXTOKENLENGTH];
+    sprintf(tmp,"%g",RDMC_SMALL);
+    a->thresh[nr] = rdmc_amanda_strtof(tmp,RDMC_SMALL);
+  }
+
+  /* finally at least one channel is geocalibratet -> so set the flag */
+  a->is_calib.geo=1;
+  return RDMC_IO_OK;
+} /* rdmc_amanda_KH() */
+
+/****************************************************************************
+ * read the ADC calibration (only nr ped beta lin)
+ ****************************************************************************/
+int rdmc_amanda_KADC_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int iom;
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if ((nargs < 4) || (nargs > 5)) return RDMC_ILF;
+
+  iom = atoi(args[1]) - 1;
+  if ((iom < 0) || (iom >= a->nch)) return RDMC_INCONSISTENT_GEOMETRY;
+  a->cal[iom].ped = rdmc_amanda_strtof(args[2],0.0);
+  a->cal[iom].beta_a = rdmc_amanda_strtof(args[3],0.0);
+  if (nargs == 4)
+      a->cal[iom].kappa = rdmc_amanda_strtof("?",0.0);
+    else
+      a->cal[iom].kappa = rdmc_amanda_strtof(args[4],0.0);
+  a->cal[iom].flag |= RDMC_CALIB_ADC;
+
+  /* set the kh flag, even if it was not set before */
+  a->is_calib.adc = 1;
+
+  return 0;
+} /* rdmc_amanda_KADC() */
+
+/****************************************************************************
+ * Read the TDC calibration (only nr beta shift alpha now)
+ ****************************************************************************/
+int rdmc_amanda_KTDC_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int iom;
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs != 5) return RDMC_ILF;
+  iom = atoi(args[1]) - 1;  
+  if ((iom < 0) || (iom >= a->nch)) return RDMC_INCONSISTENT_GEOMETRY;
+
+  a->cal[iom].beta_t =  rdmc_amanda_strtof(args[2],0.0);
+  a->cal[iom].t_0 =  rdmc_amanda_strtof(args[3],0.0);
+  a->cal[iom].alpha_t =  rdmc_amanda_strtof(args[4],0.0);
+  a->cal[iom].flag |= RDMC_CALIB_TDC;
+
+  return 0;
+
+} /* rdmc_amanda_KTDC() */
+/****************************************************************************
+ * Read the UTC calibration (only nr beta shift alpha now)
+ ****************************************************************************/
+int rdmc_amanda_KUTC_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  char *t;
+
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if (nargs != 3) return RDMC_ILF;
+
+  strcpy(a->cal_utc.utc_src,args[1]);
+
+  /* now check sec.nsec, append trailing 0's, if necessary */
+
+  t = strchr(args[2],'.');
+  if (t == NULL){
+    a->cal_utc.secs =  rdmc_amanda_strtoi(args[2],0);
+    a->cal_utc.nsecs =  rdmc_amanda_strtoi("?",0);
+  }else{
+    *t='\0';
+    a->cal_utc.secs =  rdmc_amanda_strtoi(args[2],0);
+    a->cal_utc.nsecs =  rdmc_amanda_strtoi(t,0);
+  }
+  
+  return RDMC_IO_OK;
+} /* rdmc_amanda_UTC() */
+
+int rdmc_amanda_KTOT_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int iom;
+  args = rdmc_f2k_tokenize(s,&nargs);
+  /* token + id + token arguments */
+  if ((nargs < 4) || (nargs > 5)) return RDMC_ILF;
+  iom = atoi(args[1]) - 1;  
+
+  if ((iom < 0) || (iom >= a->nch)) return RDMC_INCONSISTENT_GEOMETRY;
+
+  a->cal[iom].ped_tot = rdmc_amanda_strtof(args[2],0.0);
+  a->cal[iom].beta_tot = rdmc_amanda_strtof(args[3],1.0);
+  if (nargs == 5)
+    a->cal[iom].kappa_tot = rdmc_amanda_strtof(args[4],0.0);
+  else
+    a->cal[iom].kappa_tot = rdmc_amanda_strtof("?",0.0);
+  a->cal[iom].flag |= RDMC_CALIB_TOT;
+
+  /* set the kh flag, even if it was not set before */
+  a->is_calib.tot = 1;
+
+  return 0;
+} /* rdmc_amanda_KTOT() */
+
+int rdmc_amanda_TBEGIN_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int isec,iday,iyear;
+  char *csec="?",*cday="?",*cyear="?";
+
+  double fsec;
+  struct tm newyear;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  switch (nargs){
+  case 4:
+    cyear = args[1];
+    cday = args[2];
+    csec = args[3];
+    break;
+  case 3:
+    cyear = args[1];
+    cday = args[2];
+    break;
+  case 2:
+    cyear = args[1];
+    break;
+  case 1:
+    break;
+  default:
+   return RDMC_ILF; 
+  }
+  iyear = rdmc_amanda_strtoi(cyear, 1970);
+  iday = rdmc_amanda_strtoi(cday, 1);
+  fsec = rdmc_amanda_strtoi(csec, 0);
+
+#if 0
+  isec = rdmc_nint(fsec);
+#else
+  isec = floor(fsec);
+#endif
+  if (iyear <  0) iyear = 1970;
+  else if ((iyear < 70)) iyear += 100;
+  if (iyear > 1900) iyear -= 1900;
+  
+  isec=isec%SEC_PER_DAY ;  /* seconds of begin of day only is mod(sec,86400)*/
+
+  /* get time_t for beginning of that year */
+  newyear.tm_sec=newyear.tm_min=newyear.tm_hour
+    =newyear.tm_mday=newyear.tm_mon=newyear.tm_year
+    =newyear.tm_wday=newyear.tm_yday=newyear.tm_isdst=0;
+
+  newyear.tm_year=iyear;
+  newyear.tm_mday = 1;
+
+  a->tbegin = mktime(&newyear) + SEC_PER_DAY*(iday-1) + isec -timezone ;
+  return RDMC_IO_OK;
+}
+
+/****************************************************************************
+ * read an Event header line
+ ****************************************************************************/
+
+int rdmc_amanda_EM_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int iday,iyear;
+  char *c_enr="?",*c_nrun="?",*c_iyear="?",*c_iday="?";
+  char *c_time="0.000000000",*c_t_offset="?";
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+
+  switch (nargs){
+  case 1:
+    break;
+  case 2:
+    c_enr=args[1];
+    break;
+  case 3:
+    c_enr=args[1];
+    c_nrun=args[2];
+    break;
+  case 4:
+    c_enr=args[1];
+    c_nrun=args[2];
+    c_iyear=args[3];
+    break;
+  case 5:
+    c_enr=args[1];
+    c_nrun=args[2];
+    c_iyear=args[3];
+    c_iday=args[4];
+    break;
+  case 6:
+    c_enr=args[1];
+    c_nrun=args[2];
+    c_iyear=args[3];
+    c_iday=args[4];
+    c_time=args[5];
+    break;
+  case 7:
+    c_enr=args[1];
+    c_nrun=args[2];
+    c_iyear=args[3];
+    c_iday=args[4];
+    c_time=args[5];
+    c_t_offset=args[6];
+    break;
+  default:
+   return RDMC_ILF; 
+  }
+  e->enr = rdmc_amanda_strtoi(c_enr,RDMC_NA);
+  e->nrun = rdmc_amanda_strtoi(c_nrun,RDMC_NA);
+  iyear = rdmc_amanda_strtoi(c_iyear ,  1970);
+  iday = rdmc_amanda_strtoi(c_iday , 1);
+  rdmc_amanda_strtimetoi(c_time, &(e->secs), &(e->nsecs));
+  e->t_offset = rdmc_amanda_strtof(c_t_offset,0.0);
+
+
+  /* now patch the year in case of ssome f2k dialects and y2k-type problems */
+  iyear = rdmc_f2k_y2k(iyear);
+  e->mjd = rdmc_gps_to_mjd(iyear,iday); /* convert GPS date into mjd */
+  
+  return RDMC_IO_OK;
+} /* rdmc_amanda_EM() */
+
+int rdmc_amanda_TR_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  float azi;
+  static mtrack gen;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+  if ( nargs != 12) 
+    return RDMC_ILF;
+
+  /* get new mem for this track and init index */
+  rdmc_init_mtrack(&gen);
+
+  /* now fill it */
+  gen.tag = rdmc_amanda_strtoi(args[1], RDMC_NA);;
+  gen.parent = rdmc_amanda_strtoi(args[2], RDMC_PARENT_NA);
+  gen.id = rdmc_amanda_ipartid(args[3]);
+
+ gen.x = rdmc_amanda_strtof(args[4],RDMC_SPECIAL_NA);
+  gen.y = rdmc_amanda_strtof(args[5],RDMC_SPECIAL_NA);
+  gen.z = rdmc_amanda_strtof(args[6],RDMC_SPECIAL_NA);
+
+  gen.costh = cos(rdmc_amanda_strtof(args[7],0.)  *PID180); 
+  azi = rdmc_amanda_strtof(args[8],0.);
+  if ((azi = fmod( azi, 360.)) <0. ) azi += 360;
+  gen.phi =  azi * PID180;
+  rdmc_tau_tr(&gen); /* calc direction cosinuus from phi and costh */
+
+  gen.length = rdmc_amanda_strtof(args[9],RDMC_NA);
+  gen.e = 1000.0 * rdmc_amanda_strtof(args[10],RDMC_NA);/* GeVtoMeV (rdmc)*/
+  gen.t = rdmc_amanda_strtof(args[11],RDMC_TDC_NA);
+  gen.nmuon = 0;
+
+  rdmc_add_gen(e,&gen,e->ntrack);
+
+#if 0 /* no dynamic allocated stuff */
+  rdmc_clear_mtrack(&gen);
+#endif
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_TR() */
+
+int rdmc_amanda_CH_1x1(  mcfile *fp , array *a, 
+                              mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int nhits=0;
+  mhit h;
+  int om;
+  int j;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+  if ( nargs < 2) 
+    return RDMC_ILF;
+  else if ( ((nargs-2)%5) != 0)
+    return RDMC_ILF;
+  else if ( (nhits = (nargs-2)/5) < 1)
+    return RDMC_ILF;
+     
+  
+     /* get new mem for this track and init index */
+  rdmc_init_mhit(&h);
+  om=atoi(args[1]); /* cp ch token */
+  
+  for( j=0 ; j < nhits ; j++ ){
+    h.str=0;
+    h.ch = om-1;
+    if( j== 0)
+      h.amp = rdmc_amanda_strtof(args[1+j*5+1], RDMC_NA);
+    else
+      h.amp=RDMC_REPEAT_CH;
+    h.id = atoi(args[1+j*5+2]);
+    h.mt = rdmc_amanda_strtoi(args[1+j*5+3],RDMC_PARENT_NA);
+    h.ma = h.mt;
+    h.t = rdmc_amanda_strtof(args[1+j*5+4], RDMC_TDC_NA);
+    h.tot = rdmc_amanda_strtof(args[1+j*5+5], RDMC_NA);
+
+    rdmc_add_mhit(e,&h,e->nhits);
+
+    rdmc_clear_mhit(&h);
+
+  } /* for nhits */
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_CH() */
+
+
+int rdmc_amanda_HT_1x1( mcfile *fp , array *a, 
+                       mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  mhit h;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+  if ( nargs != 7) 
+    return RDMC_ILF;
+
+  rdmc_init_mhit(&h);
+  h.str = 0; /* this is filled later at the end of the event read */
+  h.ch = atoi(args[1])-1;
+  h.amp = rdmc_amanda_strtof(args[2] , RDMC_NA);
+  h.id = rdmc_amanda_strtoi(args[3] ,RDMC_NA);
+  h.ma = h.mt = rdmc_amanda_strtoi(args[4] ,RDMC_PARENT_NA);
+  h.t = rdmc_amanda_strtof(args[5] , RDMC_TDC_NA);
+  h.tot = rdmc_amanda_strtof(args[6], RDMC_NA);
+
+  rdmc_add_mhit(e,&h,e->nhits);
+#if 1 /* no dynamic allocated stuff */
+  rdmc_clear_mhit(&h);
+#endif
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_HT() */
+
+
+
+int rdmc_amanda_trigblock_1x1( mcfile *fp, array *ar, 
+                                    mevt *e, void *tmp){
+  int r,i; /*ret value */
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  mevt_special_t trig;
+  mevt_usesblock_t uses;
+
+  rdmc_init_mevt_special(&trig,0);
+  rdmc_init_usesblock(&uses);
+
+  /*  this should parse TRIG  */
+  if ( f2k_buff->type_def[f2k_buff->iline]->line_id == TRIG_LINE ){
+    r = TRIG_line_1x1.parser(fp,ar,e,&trig);
+    if (r != RDMC_IO_OK)
+      return RDMC_LINE_NOT_PARSED;
+  }else 
+    return RDMC_LINE_NOT_PARSED;
+
+  uses.id= e->ntrig;
+  while( ++(f2k_buff->iline) < f2k_buff->lines ){/* scan while it is possible to parse */
+    switch( f2k_buff->type_def[f2k_buff->iline]->line_id ){
+    default: 
+      r = RDMC_EVENT_NOT_RECOGNIZED;
+      --(f2k_buff->iline);
+      break;
+    case USES_LINE:
+      r = USES_line_1x1.parser(fp,ar,e,&uses);
+      break;
+    case COMMENT_LINE:
+      rdmc_append_comment(&(e->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    }
+    if (r != RDMC_IO_OK){
+      break;
+    }
+  } /* while */
+  
+  if ((r == RDMC_IO_OK) || (r ==  RDMC_EVENT_NOT_RECOGNIZED)){
+    rdmc_add_trigger(e, &trig, e->ntrig, trig.id);
+
+    for ( i=0 ; i<uses.nu ; i++) /* this is slow but will change anyway */
+      rdmc_add_trig_uses(e,&(uses.u[i]),e->ntrig_uses);
+    rdmc_clear_mevt_special(&trig,0);
+    rdmc_clear_usesblock(&uses);
+    return RDMC_IO_OK;
+  } else{
+    rdmc_f2k_errorlog(fp);
+    return r;
+  }
+}
+
+
+int rdmc_amanda_TRIG_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  mevt_special_t *trig = tmp;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+
+  int itrig,itrig_def,icount,itrig_defid;
+  char *tag_s; /* index of parent track  */
+  char *tp;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if ( nargs < 2) 
+    return RDMC_ILF;
+  tag_s = args[1];
+
+  /* now get the trigger number */
+  itrig_def = rdmc_get_hdef_tag(a->def_trig ,a->n_trigger,tag_s);
+  if (itrig_def == RDMC_NA ){
+    /* special patch for old amanda files */
+    if (strstr(tag_s, "unknown") != NULL) /*this is old rdmc ignore the line */
+      return RDMC_IO_OK;
+    else
+      return RDMC_HEADERTAG_NOTFOUND;
+  }
+  itrig_defid = a->def_trig[itrig_def].id;
+
+  rdmc_clear_mevt_special(trig,a->def_trig[itrig_def].nwords);
+  itrig = e->ntrig;
+
+  trig->id = itrig_def;
+  trig->nval = 0;
+  icount=0;
+  while ( (icount < a->def_trig[itrig_def].nwords) 
+         &&  (icount < RDMC_MAXTOKEN_PER_LINE )
+         &&   ((icount+2) < nargs) ){
+    tp = args[icount+2];
+    trig->val[icount] =  rdmc_amanda_sptof(tp);
+    icount++;
+    trig->nval=icount;
+  }
+  return RDMC_IO_OK;
+}
+
+
+int rdmc_amanda_fitblock_1x1( mcfile *fp, array *ar, 
+                                    mevt *e, void *tmp){
+  int i,r; /*ret value */
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+
+  mtrack rec;
+  mevt_special_t fresult;
+  mevt_usesblock_t uses;
+
+  rdmc_init_mtrack(&rec);  
+  rdmc_init_mevt_special(&fresult,0);
+  rdmc_init_usesblock(&uses);
+
+  /*  this should parse FIT  */
+  if ( f2k_buff->type_def[f2k_buff->iline]->line_id != FIT_LINE )
+    return RDMC_LINE_NOT_PARSED;
+
+  r = FIT_line_1x1.parser(fp,ar,e,&rec);
+  if (r != RDMC_IO_OK){
+    return RDMC_LINE_NOT_PARSED;
+  }
+
+  uses.id= e->nfit;
+
+  while( ++(f2k_buff->iline) < f2k_buff->lines ){ /* scan while it is possible to parse */
+    switch( f2k_buff->type_def[f2k_buff->iline]->line_id ){
+    default: 
+      r = RDMC_EVENT_NOT_RECOGNIZED;
+      --(f2k_buff->iline);
+      break;
+    case FRESULT_LINE:
+      r = FRESULT_line_1x1.parser(fp,ar,e,&fresult);
+      break;
+    case USES_LINE:
+      r = USES_line_1x1.parser(fp,ar,e,&uses);
+      break;
+    case COMMENT_LINE:
+      rdmc_append_comment(&(e->comment),f2k_buff->line_pt[f2k_buff->iline]);
+      break;
+    }
+    if (r != RDMC_IO_OK){
+      break;
+    }
+  } /* while */
+  
+  if ((r == RDMC_IO_OK) || (r ==  RDMC_EVENT_NOT_RECOGNIZED)){
+    rdmc_add_fit(e,&rec,&fresult,e->nfit);
+    for (i=0 ; i<uses.nu ; i++) /* this is slow but will change anyway */
+      rdmc_add_fit_uses(e,&(uses.u[i]),e->nfit_uses);
+    rdmc_clear_mtrack(&rec);  
+    rdmc_clear_mevt_special(&fresult,0);
+    rdmc_clear_usesblock(&uses);
+    return RDMC_IO_OK;
+  }else{
+    rdmc_f2k_errorlog(fp);
+    return r;
+  }
+}
+
+
+int rdmc_amanda_US_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+
+  int ius_def,icount,ius_defid;
+  char *tag_s; /* index of parent track  */
+  char *tp;
+  static mevt_special_t us;
+   
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if ( nargs < 2) 
+    return RDMC_ILF;
+  tag_s = args[1];
+
+  /* now get the user number */
+  ius_def = rdmc_get_hdef_tag(a->def_user ,a->n_user,tag_s);
+  if (ius_def == RDMC_NA ){
+    return RDMC_HEADERTAG_NOTFOUND;
+  }
+  ius_defid = a->def_user[ius_def].id;
+
+  rdmc_init_mevt_special(&us,a->def_user[ius_def].nwords);
+
+  us.id = ius_def;
+  us.nval = 0;
+  icount=0;
+  while ( (icount < a->def_user[ius_def].nwords) 
+         &&  (icount < RDMC_MAXTOKEN_PER_LINE )
+         &&   ((icount+2) < nargs) ){
+    tp = args[icount+2];
+    us.val[icount] =  rdmc_amanda_sptof(tp);
+    icount++;
+    us.nval=icount;
+  }
+  rdmc_add_user(e,&us,e->nuser);
+
+  rdmc_clear_mevt_special(&us,0);
+  return RDMC_IO_OK;
+}
+int rdmc_amanda_STATUS_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+
+  int istatus_def,icount,istatus_defid;
+  char *tag_s; /* index of parent track  */
+  char *tp;
+  static mevt_special_t status;
+   
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if ( nargs < 2) 
+    return RDMC_ILF;
+  tag_s = args[1];
+
+  /* now get the user number */
+  istatus_def = rdmc_get_hdef_tag(a->def_stat ,a->n_stat,tag_s);
+  if (istatus_def == RDMC_NA ){
+    return RDMC_HEADERTAG_NOTFOUND;
+  }
+  istatus_defid = a->def_stat[istatus_def].id;
+
+  rdmc_init_mevt_special(&status,a->def_stat[istatus_def].nwords);
+
+  status.id = istatus_def;
+  status.nval = 0;
+  icount=0;
+  while ( (icount < a->def_stat[istatus_def].nwords) 
+         &&  (icount < RDMC_MAXTOKEN_PER_LINE )
+         &&   ((icount+2) < nargs) ){
+    tp = args[icount+2];
+    status.val[icount] =  rdmc_amanda_sptof(tp);
+    icount++;
+    status.nval=icount;
+  }
+  rdmc_add_status(e,&status,e->nstat);
+
+  rdmc_clear_mevt_special(&status,0);
+  return RDMC_IO_OK;
+}
+
+int rdmc_amanda_FIT_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  mtrack *fit = tmp;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  float azi;
+  char *length_s,*energy_s;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+  switch(nargs){
+  case 9:
+    length_s = energy_s="?";
+  case 10:
+    length_s = args[9];
+    energy_s = "?";
+    break;
+  case 11:
+    length_s = args[9]; 
+    energy_s = args[10];
+    break;
+  default:
+    return RDMC_ILF;
+  }
+  /* get new mem for this track and init index */
+  rdmc_clear_mtrack(fit);
+
+  /* now fill it */
+  fit->tag = rdmc_amanda_strtoi(args[1], RDMC_NA);;
+  fit->id = rdmc_amanda_ipartid(args[2]);
+  fit->x = rdmc_amanda_strtof(args[3],RDMC_SPECIAL_NA);
+  fit->y = rdmc_amanda_strtof(args[4],RDMC_SPECIAL_NA);
+  fit->z = rdmc_amanda_strtof(args[5],RDMC_SPECIAL_NA);
+
+
+  fit->costh = cos(rdmc_amanda_strtof(args[6],0.)  *PID180); 
+  azi = rdmc_amanda_strtof(args[7],0.);
+  if ((azi = fmod( azi, 360.)) <0. ) azi += 360;
+  fit->phi =  azi * PID180;
+  rdmc_tau_tr(fit); /* calc direction cosinus from phi and costh */
+
+  fit->t = rdmc_amanda_strtof(args[8],RDMC_TDC_NA);
+  fit->length = rdmc_amanda_strtof(length_s,RDMC_BIG);
+  fit->e = 1000.0 * rdmc_amanda_strtof(energy_s,0.);/* GeVtoMeV (rdmc)*/
+
+  return RDMC_IO_OK;
+}
+
+int rdmc_amanda_FRESULT_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  mevt_special_t *fresult = tmp;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int ifit_id;
+
+  int ifit_def,icount,ifit_defid;
+  char *tp;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if ( nargs < 2) 
+    return RDMC_ILF;
+  /* now get the trigger number */
+  ifit_id=atoi(args[1]);
+  ifit_def = rdmc_get_hdef_id(a->def_fit ,a->n_fit,ifit_id);
+  if (ifit_def == RDMC_NA ){
+    return RDMC_HEADERTAG_NOTFOUND;
+  }
+  ifit_defid = a->def_fit[ifit_def].id;
+
+  rdmc_clear_mevt_special(fresult,a->def_fit[ifit_def].nwords);
+
+  fresult->id = ifit_def;
+  fresult->nval = 0;
+  icount=0;
+  while ( (icount < a->def_fit[ifit_def].nwords) 
+         &&  (icount < RDMC_MAXTOKEN_PER_LINE )
+         &&   ((icount+2) < nargs) ){
+    tp = args[icount+2];
+    fresult->val[icount] =  rdmc_amanda_sptof(tp);
+    icount++;
+    fresult->nval=icount;
+  }
+  return RDMC_IO_OK;
+}
+
+int rdmc_amanda_USES_1x1(mcfile *fp, array *a, mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  mevt_usesblock_t  *uses = tmp; /* uses HAS to be initilized and uses.id 
+                                   has to be set ! */
+  int n_allocated=0;
+  int i;
+  char *c;
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+  if ( nargs < 1) 
+    return RDMC_ILF;
+
+  /* nasty but cannot be done differently */
+  n_allocated = uses->nu + RDMC_MAXTOKEN_PER_LINE;
+  uses->u = realloc(uses->u ,n_allocated * sizeof(mevt_uses_t) );
+
+  for ( i=1 ; i < nargs ; i++){
+    if (uses->nu >= n_allocated-1){
+      n_allocated += RDMC_MAXTOKEN_PER_LINE;
+      uses->u = realloc( uses->u , n_allocated*sizeof(mevt_uses_t));
+    }
+    if (strcmp(args[i],"all") == 0 ){
+      uses->u[uses->nu].hitid = -1; /* all hits ! */
+      uses->u[uses->nu].useid = uses->id;
+      uses->nu++;
+    } else if ( (c = strchr(args[i],'-')) != NULL){
+      int ilow,iup,nnew,j;
+      *c='\0';
+      ilow=atoi(args[i]);
+      iup=atoi(c+1);
+      nnew =  1 + iup - ilow;
+      for (j = 0 ; j <  nnew ; j++){
+       if (uses->nu >= n_allocated-1){
+         n_allocated += RDMC_MAXTOKEN_PER_LINE;
+         uses->u = realloc( uses->u , n_allocated*sizeof(mevt_uses_t));
+       }
+       uses->u[uses->nu].hitid = ilow+j; /* all hits ! */
+       uses->u[uses->nu].useid = uses->id;
+       uses->nu++;
+      }
+    }else{
+      uses->u[uses->nu].hitid = atoi(args[i]); /* all hits ! */
+      uses->u[uses->nu].useid = uses->id;
+      uses->nu++;
+    }
+  } /* for */
+
+  return RDMC_IO_OK;
+}
+
+/************************************************/
+/***********write functions ********************/
+/*************************************************/
+
+
+int rdmc_wfoot_f2k_1x1_2(const mcfile *fp,const array *a, const mevt *e){
+  /* now write the dummy tend line */
+  fputs("TEND ? ? ?\n",fp->fp); 
+  fputs("END\n",fp->fp); 
+  return 0;
+}
+
+/****************************************************************************
+ * wrhist_amanda() writes history lines to an ASCII file
+ ****************************************************************************/
+
+int rdmc_wrhist_f2k_1x1(const mcfile *fp, const char *s, const char *pre)
+{
+  const char *bol;                               /* beginning of the line */
+
+  int pre_len=0;
+  int max_step=0;
+
+  if ((s== NULL)|| (pre == NULL))
+    return RDMC_IO_OK;
+
+  /* init */
+  pre_len = strlen(pre);
+  bol=s;
+
+  /* maximum to write */
+  max_step = F2000_MAXLINE - pre_len - RDMC_MAXTOKENLENGTH ; 
+  if (max_step <= 0) 
+    return RDMC_ILF;
+  
+  while (1) {
+    int do_exit=0;
+    int icount=0;
+    char line[RDMC_MAXLINE+1]="";          /* temporary copy of the string */
+
+    while (do_exit == 0){ /* print this line */
+      if ((*bol)=='\0'){ /* end of string */
+       return RDMC_IO_OK;
+      }else if ((*bol) == '\n'){ /* end of line */
+       if(icount > 0){
+         line[icount]='\0';
+         fputs(pre,fp->fp);fputs(line,fp->fp); putc('\n',fp->fp);
+         /*fprintf(fp->fp, "%s%s\n", pre, line);*/
+       }
+       ++(bol);
+       do_exit =1;
+      } else if ((*bol) == '\\'){ /* cont line */
+       line[icount] = '\0';
+       strcat(line,"\\");
+       fputs(pre,fp->fp);fputs(line,fp->fp); putc('\n',fp->fp);
+       /*fprintf(fp->fp, "%s%s\n", pre, line); */
+       ++(bol);
+       do_exit =1;
+
+      } else if ((icount) >=  (max_step+1)){ /* cont line */
+       line[icount]='\0';
+       strcat(line,"\\");
+       fputs(pre,fp->fp);fputs(line,fp->fp); putc('\n',fp->fp);
+       /*fprintf(fp->fp, "%s%s\n", pre, line);*/
+       do_exit =1;
+      } else { /* just copy */
+       line[icount] = *bol;
+       ++icount;
+       ++(bol);
+       do_exit = 0 ;
+      }  
+    } /* print this line */
+  }
+
+} /* wrhist_amanda() */
+
+/****************************************************************************
+ * wrcomment_amanda() writes a comment line to an ASCII file
+ ****************************************************************************/
+
+int rdmc_wrcomment_f2k_1x1(const mcfile *fp, const char *s)
+{      
+  static char *ts=NULL;
+  char line[F2000_MAXLINE+1];              /* temporary copy of the string */
+  char *eol;                                    /* end of current line */
+  char *bol;                                  /* beginning of the line */
+  if (s != NULL){
+    /* get a local copy due to const decl */
+#ifndef CRAY
+    ts = alloca(sizeof(char)*(strlen(s)+1));
+#else
+    ts = realloc(ts,sizeof(char)*(strlen(s)+1));
+#endif
+    strcpy(ts,s);
+
+    bol=ts;
+    while(*bol){
+      int thislen;
+      eol = strchr(bol,'\n');
+      if (eol){
+       thislen = 1 + (int) (eol-bol) ;
+       if (thislen <=  1){
+         putc('\n',fp->fp);
+       /*fprintf(fp->fp, "\n"); */
+       }else if (thislen <= F2000_MAXLINE) {
+         *eol='\0';
+         fputs(bol,fp->fp); putc('\n',fp->fp);
+         /*fprintf(fp->fp, "%s\n", bol);*/
+       }else {
+         strncpy(line,bol,F2000_MAXLINE-2);
+         line[F2000_MAXLINE-2]='\\';
+         line[F2000_MAXLINE-1]='\0';
+         fputs(line,fp->fp); putc('\n',fp->fp);
+         /* fprintf(fp->fp, "%s\n",line); */
+         eol = bol + (F2000_MAXLINE-4);
+         *(eol + 1) = '!';
+       }
+       bol=eol+1;
+      }else
+       break;
+    }
+  }
+
+  return RDMC_IO_OK;
+} /* wrcomment_amanda() */
+
+
+int rdmc_whead_f2k_1x1_2(const mcfile *fp,const array *geo, const mevt *e)
+{
+  int iom;                                              /* om index in loop */
+  int itrigger;                                    /* trigger index in loop */
+  int istat;
+  int ifit,iuser;
+  int array_defined=0;  /* is the array line to be written) */
+
+  fprintf(fp->fp, "V 2000.%i.%i\n",                     /* write the V flag */
+         AMANDA_ASCII_VERSION, AMANDA_ASCII_MINOR);       /* version number */
+
+  if (fp->creator !=NULL )
+    rdmc_wrhist_f2k_1x1(fp,fp->creator,"HI ");           /* write history lines */
+  if (fp->comment != NULL)                 /* if there is a common comment */
+    rdmc_wrcomment_f2k_1x1(fp, fp->comment);
+
+  if (geo->comment != NULL)                 /* if there is a common comment */
+    rdmc_wrcomment_f2k_1x1(fp, geo->comment);
+
+  /* thest if array is to be written */
+  if ((geo->is_calib.geo)
+      || ( geo->is_calib.tdc)
+      || (geo->is_calib.adc)
+#if USES_TOT_CAL /* not in f2000 1.1 */
+      || (geo->is_calib.tot)
+#endif
+      || (geo->nch >0 )
+      ){
+    array_defined =1;
+  }
+
+  /* first write the geometry Block header */
+  if (array_defined) {     /* if there was a detector geometry */
+    fprintf(fp->fp,"ARRAY %s %g %g %g %i %i\n",
+           rdmc_amanda_sdet(geo->id), 
+           geo->longitude, geo->lattitude,
+           geo->depth, geo->nstr, geo->nch);         /* 'ARRAY' flag */
+  }  
+  
+
+
+  /**************** now the trigger block ***********************/
+  
+  for (itrigger = 0; itrigger < geo->n_trigger; itrigger++) { 
+    int i;
+    fprintf(fp->fp, "TRIG_DEF %i %s", /* write trigger lines */
+           geo->def_trig[itrigger].id, 
+           geo->def_trig[itrigger].tag);
+    for (i=0 ; i< geo->def_trig[itrigger].nwords ; i++){
+      putc(' ',fp->fp); fputs(geo->def_trig[itrigger].words[i],fp->fp);
+      /*fprintf(fp->fp," %s",geo->def_trig[itrigger].words[i]); */
+    }
+    putc('\n',fp->fp); /*fprintf(fp->fp,"\n"); */
+    if (geo->def_trig[itrigger].npars >0 ){ /* write trigger par lines */
+
+      fputs("TRIG_PAR ",fp->fp);fputs(geo->def_trig[itrigger].tag,fp->fp);
+      /* fprintf(fp->fp, "TRIG_PAR %s"
+        ,geo->def_trig[itrigger].tag); */
+      for (i=0 ; i< geo->def_trig[itrigger].npars ; i++){
+       putc(' ',fp->fp); fputs(geo->def_trig[itrigger].pars[i],fp->fp);
+       /*fprintf(fp->fp," %s",geo->def_trig[itrigger].pars[i]);*/
+      }
+      putc('\n',fp->fp);/* fprintf(fp->fp,"\n");  */
+    }
+  } /* for itrigger */
+
+  
+  /** write now the calibration ('K???') of all channels, if there is one *****/
+  /* first theKH line */
+  if ( geo->is_calib.tdc
+       || geo->is_calib.adc
+#if USES_TOT_CAL /* not in f2000 1.1 */
+       || geo->is_calib.tot
+#endif
+       || geo->is_calib.utc){
+    fputs("KH",fp->fp); /*fprintf(fp->fp,"KH"); */
+    if ( geo->is_calib.adc)
+      fputs(" ADC",fp->fp); /*fprintf(fp->fp," ADC"); */
+    if ( geo->is_calib.tdc)
+      fputs(" TDC",fp->fp); /* fprintf(fp->fp," TDC"); */
+    if ( geo->is_calib.utc)
+      fputs(" UTC",fp->fp);  /* fprintf(fp->fp," UTC");*/
+#if USES_TOT_CAL 
+    if ( geo->is_calib.tot)
+      fputs(" TOT",fp->fp);  /* fprintf(fp->fp," TOT"); */
+#endif
+    putc('\n',fp->fp); /* fprintf(fp->fp,"\n"); */
+  }
+  
+  /* now the stat_def -> these are only strings ! */
+  for (istat=0 ; istat < geo->n_stat ; istat++){
+    int i;
+    fputs("STAT_DEF ",fp->fp); fputs(geo->def_stat[istat].tag,fp->fp);
+    /* fprintf(fp->fp, "STAT_DEF"); fprintf(fp->fp, " %s",geo->def_stat[istat].tag); */
+    for (i=0 ; i< geo->def_stat[istat].nwords ; i++){
+      putc(' ',fp->fp); fputs(geo->def_stat[istat].words[i],fp->fp);
+      /* fprintf(fp->fp," %s",geo->def_stat[istat].words[i]); */
+    }
+    putc('\n',fp->fp);/* fprintf(fp->fp,"\n"); */
+    /* write STAT_DEF lines */
+  }
+  
+  /* now the FIT_DEF -> these are  ! */
+  for (ifit=0 ; ifit < geo->n_fit ; ifit++){
+    int i;
+    fprintf(fp->fp, "FIT_DEF %i %s", /* write trigger lines */
+           geo->def_fit[ifit].id, 
+           geo->def_fit[ifit].tag);
+    for (i=0 ; i< geo->def_fit[ifit].nwords ; i++){
+      putc(' ',fp->fp); fputs(geo->def_fit[ifit].words[i],fp->fp);
+      /* fprintf(fp->fp," %s",geo->def_fit[ifit].words[i]);*/
+    }
+    putc('\n',fp->fp); /*fprintf(fp->fp,"\n"); */
+    /* write FIT_DEF lines */
+  }
+  
+  /********* write now the positions ('OM') of all channels ***************/
+  
+  if (geo->is_calib.geo){
+    for (iom = 0 ; iom < geo->nch ; iom++) {
+      fprintf(fp->fp,"OM %i %i %i %g %g %g %2s %s %s %g %g\n",
+             iom+1, 
+             geo->clust[iom]+1,
+             geo->str[iom],
+             geo->x[iom], geo->y[iom], geo->z[iom],
+             rdmc_amanda_sori(geo->costh[iom]),
+             rdmc_amanda_spmtid(geo->type[iom]),
+             rdmc_amanda_itostr(geo->serial[iom],RDMC_NA),
+             geo->sensit[iom],
+             geo->thresh[iom]);
+    } /* for iom */  
+  }
+  
+  /*
+   * Write ADC/TDC/UTC calibration entries
+   */
+  if (geo->is_calib.adc)
+    for (iom = 0; iom < geo->nch; iom++)
+      fprintf(fp->fp,"KADC %i %g %g %g\n",
+             iom+1,
+             geo->cal[iom].ped,
+             geo->cal[iom].beta_a,
+             geo->cal[iom].kappa);
+  
+  if (geo->is_calib.tdc)
+    for (iom = 0; iom < geo->nch; iom++)
+      fprintf(fp->fp,"KTDC %i %g %g %g\n",
+             iom+1,
+             geo->cal[iom].beta_t,
+             geo->cal[iom].t_0,
+             geo->cal[iom].alpha_t);
+  if (geo->is_calib.tot)
+#if USE_TOT_CAL
+    for (iom = 0; iom < geo->nch; iom++)
+      fprintf(fp->fp,"KTOT %i %g %g %g\n",
+             iom+1,
+             geo->cal[iom].ped_tot,
+             geo->cal[iom].beta_tot,
+             geo->cal[iom].kappa_tot);
+#endif
+  if (geo->is_calib.utc){
+    fprintf(fp->fp, "KUTC %s %i.%09i\n",geo->cal_utc.utc_src
+           ,geo->cal_utc.secs,geo->cal_utc.nsecs);
+  }
+  
+
+  /* now the USER_DEF -> these are  ! */
+  for (iuser=0 ; iuser < geo->n_user ; iuser++){
+    int i;
+     fputs("USER_DEF ",fp->fp); fputs(geo->def_user[iuser].tag,fp->fp);
+     /* fprintf(fp->fp, "USER_DEF %s", geo->def_user[iuser].tag); */
+     for (i=0 ; i< geo->def_user[iuser].nwords ; i++){
+       putc(' ',fp->fp); fputs(geo->def_user[iuser].words[i],fp->fp);
+       /*fprintf(fp->fp," %s",geo->def_user[iuser].words[i]); */
+     }
+     putc('\n',fp->fp);/* fprintf(fp->fp,"\n");*/
+    /* write USER_DEF lines */
+  }
+
+  /* now write the tbegin line */
+  if (geo->tbegin > 0){ 
+    struct tm *gmt;
+
+    gmt = gmtime(&(geo->tbegin));
+       fprintf(fp->fp, "TBEGIN %i %i %i\n", /* write trigger lines */
+              1900+gmt->tm_year,gmt->tm_yday+1,
+              gmt->tm_hour*3600+gmt->tm_min*60+gmt->tm_sec
+              );
+  } else {
+    fputs( "TBEGIN ? ? ?\n",fp->fp); /*fprintf(fp->fp, "TBEGIN ? ? ?\n"); */
+  }
+
+  return 0;
+} /* warr_amanda() */
+
+
+/****************************************************************************
+ * function wevt_amanda() writes an event to a amanda-like file
+ ****************************************************************************/
+
+int rdmc_wevt_f2k_1x1_2(const mcfile *fp,const array *ar, const mevt *event)
+{
+  int itok, i;
+  char *upt;
+  float channel;
+  
+  unsigned long format_version= 100*fp->fmajor + fp->fminor;
+   
+  /*
+   * write Event header and comments
+   */
+
+  /* i have an event 0 at every begin ??? throw it away */
+  /*  if(event->enr == 0)return 0 ; */
+
+  {
+    int gpsyear,gpsday;
+    rdmc_mjd_to_gps(event->mjd, &gpsyear, &gpsday);/* GPS/UT year and day */
+    fprintf(fp->fp, "EM %i %i %s", event->enr,event->nrun
+           ,rdmc_amanda_itostr(gpsyear,RDMC_NA));
+
+    fprintf(fp->fp, " %s %i.%09i %g\n"
+           ,rdmc_amanda_itostr(gpsday,RDMC_NA)
+           ,event->secs,(event->nsecs>=0)?event->nsecs:0,
+           event->t_offset);
+  }
+
+  if (event->comment != NULL)                /* if there is an event comment */
+    rdmc_wrcomment_f2k_1x1(fp, event->comment);
+
+
+  /*
+   * write tracks
+   */
+  for (itok=0; itok<event->ntrack; itok++){ /* write  the 'TR' lines */
+    fprintf(fp->fp,"TR %i %s %s %g %g %g %g %g %s"
+           , event->gen[itok].tag
+           ,rdmc_amanda_itostr(event->gen[itok].parent,RDMC_PARENT_NA)
+           ,rdmc_amanda_spartid(event->gen[itok].id)
+           ,event->gen[itok].x,
+           event->gen[itok].y,
+           event->gen[itok].z,
+           acos(event->gen[itok].costh)/PID180,
+           event->gen[itok].phi/PID180
+           ,rdmc_amanda_ftostr(event->gen[itok].length,RDMC_BIG));
+    fprintf(fp->fp, " %s",rdmc_amanda_ftostr(event->gen[itok].e/1000.,RDMC_NA));
+    fprintf(fp->fp, " %s\n",rdmc_amanda_ftostr(event->gen[itok].t,RDMC_TDC_NA));
+  }
+
+  /*
+   * write hits
+   */
+  for (itok = 0; itok < event->nhits; itok++){
+    fprintf(fp->fp, "HT %i",event->h[itok].ch+1);
+
+    if (event->h[itok].amp == RDMC_REPEAT_CH)
+      fputs(" *",fp->fp);
+    else{
+      putc(' ',fp->fp); fputs(rdmc_amanda_ftostr(event->h[itok].amp,RDMC_NA),fp->fp); }
+    /* fprintf(fp->fp, " %s",rdmc_amanda_ftostr(event->h[itok].amp,RDMC_NA));*/
+
+    fprintf(fp->fp, " %i",event->h[itok].id);
+    if (event->h[itok].mt == RDMC_PARENT_NOISE)
+      fputs(" N",fp->fp);
+    else if(event->h[itok].mt == RDMC_PARENT_AFPULS)  
+      fputs(" A",fp->fp);
+    else{
+      putc(' ',fp->fp); 
+      fputs(rdmc_amanda_itostr(event->h[itok].mt,RDMC_PARENT_NA),fp->fp);
+    }
+    putc(' ',fp->fp); fputs(rdmc_amanda_ftostr(event->h[itok].t,RDMC_TDC_NA),fp->fp);
+    putc(' ',fp->fp); fputs(rdmc_amanda_ftostr(event->h[itok].tot,RDMC_NA),fp->fp);
+    if ( (format_version ) >= 102 ){ /* only in case of minor f2k.1.2 and further version */
+       if (event->h[itok].hstat.n_tdc_edges || event->h[itok].hstat.tdc_flag){
+           putc(' ',fp->fp);
+           if (event->h[itok].hstat.tdc_flag) putc('>',fp->fp);
+           fprintf(fp->fp, "%i",event->h[itok].hstat.n_tdc_edges);
+       }
+    }
+
+    putc('\n',fp->fp);
+    /*      fprintf(fp->fp, " %s",rdmc_amanda_itostr(event->h[itok].mt,RDMC_PARENT_NA));
+    fprintf(fp->fp, " %s",
+           rdmc_amanda_ftostr(event->h[itok].t,RDMC_TDC_NA));
+    fprintf(fp->fp, " %s\n", 
+           rdmc_amanda_ftostr(event->h[itok].tot,RDMC_NA));
+    */
+  }
+
+
+  /*
+   * write waveforms
+   */
+  /*  float channel; */
+  
+  if ( (format_version ) >= 102 ){ /* only in case of minor f2k.1.2 and further version */
+      for (itok = 0; itok < event->nwf; itok++){
+         
+         channel = event->wf[itok].om + event->wf[itok].ch/100.;
+         
+         fprintf(fp->fp, "WF %4.2f", channel); 
+         putc(' ',fp->fp);  
+         fputs(rdmc_amanda_itostr(event->wf[itok].id, RDMC_NA),fp->fp); 
+         putc(' ',fp->fp);  
+         fputs(rdmc_amanda_itostr(event->wf[itok].pa, RDMC_PARENT_NA),fp->fp);
+         fprintf(fp->fp, " %i",event->wf[itok].ndigi);
+         putc(' ',fp->fp);  
+         fputs(rdmc_amanda_ftostr(event->wf[itok].t_start,RDMC_NA),fp->fp); 
+         putc(' ',fp->fp);  
+         fputs(rdmc_amanda_ftostr(event->wf[itok].t_bin,RDMC_NA),fp->fp); 
+         if ( (format_version ) >= 200401 ){ /* only in case of minor f2k.2004.1 and further version */
+             putc(' ',fp->fp);  
+             fputs(rdmc_amanda_ftostr(event->wf[itok].baseline,RDMC_WF_BASELINE_NA),fp->fp); 
+         }
+         for ( i=0; i<event->wf[itok].ndigi; i++){
+             /*      if(i!=0&&i%10 == 0) fprintf(fp->fp, "\n&"); // continuation line  */
+             /* doesn't work with reading */
+             /*     fprintf(fp->fp, " %6.1f",event->wf[itok].digi[i]);*/
+             putc(' ',fp->fp); 
+             fputs(rdmc_amanda_ftostr((int)((event->wf[itok].digi[i])*10)/10.,RDMC_TDC_NA),fp->fp);
+         }
+         putc('\n',fp->fp);
+      }
+  }
+       
+  /*
+   * write trigger lines
+   */
+  for (itok = 0; itok < event->ntrig ; itok++){
+    int id;
+    int i;
+    id = event->ptrig[itok].id;
+    if ( (id < ar->n_trigger ) ){
+      fputs("TRIG ",fp->fp); fputs(ar->def_trig[id].tag,fp->fp);
+      /*fprintf(fp->fp, "TRIG %s", ar->def_trig[id].tag); */
+      for ( i=0  ;  i < event->ptrig[itok].nval ; i++){
+       fprintf(fp->fp, " %g" ,event->ptrig[itok].val[i]);
+      }
+      putc('\n',fp->fp); /*fprintf(fp->fp, "\n"); */
+      /* 
+        write trigger uses lines
+      */
+      upt = rdmc_amanda_uses_to_str(event->ntrig_uses,event->trig_uses,itok);
+      if (upt[0] != '\0'){ 
+       fputs(upt,fp->fp); /*fprintf(fp->fp, "%s",upt); */
+      }
+    }
+  }
+
+
+  /* 
+     write status  lines 
+  */
+  for (itok = 0; itok < event->nstat ; itok++){
+    int id;
+    int i;
+    id = event->status[itok].id;
+    if (id < ar->n_stat  ){
+       fputs("STATUS ",fp->fp); fputs(ar->def_stat[id].tag,fp->fp);
+       /* fprintf(fp->fp, "STATUS %s", ar->def_stat[id].tag); */
+      for ( i=0  ;  i < event->status[itok].nval ; i++){
+       fprintf(fp->fp, " %g" ,event->status[itok].val[i]);
+      }
+      putc('\n',fp->fp); /* fprintf(fp->fp, "\n"); */
+    }
+  }
+
+  
+  /*
+   * write fits
+   */
+  for (itok = 0; itok < event->nfit; itok++){
+    fprintf(fp->fp, "FIT %i %s %g %g %g %g %g %g",
+           event->rec[itok].tag,
+           rdmc_amanda_spartid(event->rec[itok].id),
+           event->rec[itok].x,
+           event->rec[itok].y,
+           event->rec[itok].z,
+           acos(event->rec[itok].costh)/PID180,
+           event->rec[itok].phi/PID180,
+           event->rec[itok].t);
+    putc(' ',fp->fp);  fputs(rdmc_amanda_ftostr(event->rec[itok].length,RDMC_BIG),fp->fp);
+    putc(' ',fp->fp);  fputs(rdmc_amanda_ftostr(event->rec[itok].e/1000.,0.),fp->fp);
+    putc('\n',fp->fp); 
+    /*
+    fprintf(fp->fp, " %s"
+           ,rdmc_amanda_ftostr(event->rec[itok].length,RDMC_BIG));
+    fprintf(fp->fp, " %s\n",rdmc_amanda_ftostr(event->rec[itok].e/1000.,0.));
+    */
+    
+    {/*      write fresult   */
+      int id;
+      int i;
+      id = event->fresult[itok].id;
+      if ((id>=0 ) && (id < ar->n_fit )){
+       fprintf(fp->fp, "FRESULT %i", 
+               ar->def_fit[id].id);
+       for ( i=0  ;  i < event->fresult[itok].nval ; i++){
+         putc(' ',fp->fp);  
+         fputs(rdmc_amanda_ftostr(event->fresult[itok].val[i], 
+                                  RDMC_SPECIAL_NA),fp->fp);
+         /* fprintf(fp->fp, " %s",
+            rdmc_amanda_ftostr(event->fresult[itok].val[i],
+            RDMC_SPECIAL_NA)); */
+       }
+       putc('\n',fp->fp); /* fprintf(fp->fp, "\n"); */
+      }
+    }
+
+    /* 
+       fuses lines
+    */
+    upt = rdmc_amanda_uses_to_str(event->nfit_uses,event->fit_uses,itok);
+    if (upt[0] != '\0'){ 
+      fputs(upt,fp->fp); /* fprintf(fp->fp, "%s",upt); */
+    }
+  }
+
+
+  /*
+   * write user defined lines
+   */
+  /*  fprintf(stderr,"*** rdmc %i\n",event->nuser); */
+  for (itok = 0; itok < event->nuser ; itok++){
+    int id;
+    int i;
+    id = event->user[itok].id;
+    /*    fprintf(stderr,"*** rdmc %i %i %i\n",id,ar->n_user,ar->def_user[0].nwords); */
+    if (id < ar->n_user  ){
+      fputs("US ",fp->fp); fputs(ar->def_user[id].tag,fp->fp);
+      /* fprintf(fp->fp, "US %s", ar->def_user[id].tag); */
+      for ( i=0  ;  i < event->user[itok].nval ; i++){
+       fprintf(fp->fp, " %g" ,event->user[itok].val[i]);
+      }
+      putc('\n',fp->fp);  /*fprintf(fp->fp, "\n"); */
+    }
+  }
+  fputs("EE\n",fp->fp); /* fprintf(fp->fp, "EE\n"); */
+
+  return 0;
+} /* function wevt_amanda() */
+
+
+
+
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
+
+
+
diff --git a/RALICE/icepack/iceconvert/f2k_1x2.c b/RALICE/icepack/iceconvert/f2k_1x2.c
new file mode 100644 (file)
index 0000000..44d20b6
--- /dev/null
@@ -0,0 +1,136 @@
+
+/* implement functions special for the f2k 1.2 format */
+#include <stdlib.h>
+
+#include "rdmc.h"
+#include "amanda.h"
+#include "f2k.h"
+
+const f2000_line_t HT_line_1x2 = 
+  {"HT ", HT_LINE, COMP_STRINGWISE, rdmc_amanda_HT_1x2 };
+const f2000_line_t WF_line_1x2 = 
+  {"WF ", WF_LINE, COMP_STRINGWISE, rdmc_amanda_WF_1x2 };               // pd
+
+
+const f2000_event_t f2000_mevt_1x2 =
+{ RDMC_EVENT_MUON,
+  { &(EM_line_1x1),
+    NULL
+  },
+  {
+    &(TR_line_1x1),
+    &(HT_line_1x2),  &(CH_line_1x1),    
+    &(WF_line_1x2),
+    &(STATUS_line_1x1),   &(US_line_1x1),
+    &(FIT_block_1x1),  &(FRESULT_line_1x1),
+    &(TRIG_block_1x1), &(USES_line_1x1),
+    &(COMMENT_line_1x1)
+    ,  NULL
+  },
+  { &(EE_line_1x1)
+    , NULL},
+  rdmc_mevt_f2k_1x1,
+  rdmc_wevt_f2k_1x1_2
+};
+
+
+const f2000_event_t  * f2000_events_1x2[] 
+  = { 
+    &f2000_mevt_1x2,
+    NULL 
+  };
+
+
+int rdmc_amanda_HT_1x2( mcfile *fp , array *a, 
+                       mevt *e, void *tmp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  mhit h;
+  char *c_stat="";
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);
+
+  switch (nargs){
+  case 7:
+    break;
+  case 8:
+    c_stat=args[7];
+    break;
+  default:
+    return RDMC_ILF;
+  }
+
+  rdmc_init_mhit(&h);
+  h.str = 0; /* this is filled later at the end of the event read */
+  h.ch = atoi(args[1])-1;
+  h.amp = rdmc_amanda_strtof(args[2] , RDMC_NA);
+  h.id = rdmc_amanda_strtoi(args[3] ,RDMC_NA);
+  h.ma = h.mt = rdmc_amanda_strtoi(args[4] ,RDMC_PARENT_NA);
+  h.t = rdmc_amanda_strtof(args[5] , RDMC_TDC_NA);
+  h.tot = rdmc_amanda_strtof(args[6], RDMC_NA);
+
+  if (rdmc_amanda_mhit_stat(&(h.hstat),c_stat) != RDMC_IO_OK)
+    return RDMC_ILF;
+
+  rdmc_add_mhit(e,&h,e->nhits);
+#if 1 /* no dynamic allocated stuff */
+  rdmc_clear_mhit(&h);
+#endif
+
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_HT() */
+
+int rdmc_amanda_WF_1x2( mcfile *fp , array *a, mevt *e, void *tmp)
+{
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int i;
+  waveform wf;
+  float channel;
+
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);                   //check the parsing string
+
+  if ( nargs < 7) return RDMC_ILF;                      // check # 
+
+  rdmc_init_WF(&wf);  
+  channel    = rdmc_amanda_strtof(args[1], RDMC_NA);    // fill waveform struct 
+  wf.om      = rdmc_nint(channel);
+  wf.ch      = (channel - wf.om) * 100.;
+  wf.id      = rdmc_amanda_strtoi(args[2] ,RDMC_NA);
+  wf.pa      = rdmc_amanda_strtoi(args[3] ,RDMC_PARENT_NA);
+  wf.ndigi   = atoi(args[4]);
+  wf.t_start = rdmc_amanda_strtof(args[5], RDMC_NA);
+  wf.t_bin   = rdmc_amanda_strtof(args[6], RDMC_NA);
+  if ( nargs < 7 + wf.ndigi)  return RDMC_ILF;          // check # 
+
+  if( wf.ndigi <= 0 || wf.ndigi > RDMC_MAXDIGI )
+    return RDMC_ILF;
+      
+  wf.digi   = malloc(wf.ndigi*sizeof(float));           // fill digit. of waveform
+  for (i = 0; i < wf.ndigi; i++)
+    wf.digi[i] = rdmc_amanda_strtof(args[7+i], RDMC_TDC_NA);
+
+
+  rdmc_add_WF(e,&wf,e->nwf);                            // add waveform to event
+  rdmc_clear_WF(&wf);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_WF() */
+
+// pd - end
+
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
+
+
+
diff --git a/RALICE/icepack/iceconvert/f2k_1x3.c b/RALICE/icepack/iceconvert/f2k_1x3.c
new file mode 100644 (file)
index 0000000..aaef354
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+/* implement functions special for the f2k 1.3 format */
+
+#include "rdmc.h"
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
diff --git a/RALICE/icepack/iceconvert/f2k_1x4.c b/RALICE/icepack/iceconvert/f2k_1x4.c
new file mode 100644 (file)
index 0000000..16650c6
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+/* implement functions special for the f2k 1.4 format */
+
+#include "rdmc.h"
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
diff --git a/RALICE/icepack/iceconvert/f2k_2004x1.c b/RALICE/icepack/iceconvert/f2k_2004x1.c
new file mode 100644 (file)
index 0000000..cc75235
--- /dev/null
@@ -0,0 +1,95 @@
+
+/* implement functions special for the f2k 1.2 format */
+#include <stdlib.h>
+
+#include "rdmc.h"
+#include "amanda.h"
+#include "f2k.h"
+
+const f2000_line_t WF_line_2004x1 = 
+  {"WF ", WF_LINE, COMP_STRINGWISE, rdmc_amanda_WF_2004x1 };
+
+
+
+const f2000_event_t f2000_mevt_2004x1 =
+{ RDMC_EVENT_MUON,
+  { &(EM_line_1x1),
+    NULL
+  },
+  {
+    &(TR_line_1x1),
+    &(HT_line_1x2),  &(CH_line_1x1),    
+    &(WF_line_2004x1),
+    &(STATUS_line_1x1),   &(US_line_1x1),
+    &(FIT_block_1x1),  &(FRESULT_line_1x1),
+    &(TRIG_block_1x1), &(USES_line_1x1),
+    &(COMMENT_line_1x1)
+    ,  NULL
+  },
+  { &(EE_line_1x1)
+    , NULL},
+  rdmc_mevt_f2k_1x1,
+  rdmc_wevt_f2k_1x1_2
+};
+
+
+const f2000_event_t  * f2000_events_2004x1[] 
+  = { 
+    &f2000_mevt_2004x1,
+    NULL 
+  };
+
+
+int rdmc_amanda_WF_2004x1( mcfile *fp , array *a, mevt *e, void *tmp)
+{
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  char *s=f2k_buff->line_pt[f2k_buff->iline];
+  char **args=NULL;
+  int nargs=0;
+  int i;
+  waveform wf;
+  float channel;
+
+
+  /* start parsing*/
+  args = rdmc_f2k_tokenize(s,&nargs);                   //check the parsing string
+
+  if ( nargs < 8) return RDMC_ILF;                      // check # 
+
+  rdmc_init_WF(&wf);  
+  channel    = rdmc_amanda_strtof(args[1], RDMC_NA);   // fill waveform struct 
+  wf.om      = rdmc_nint(channel);
+  wf.ch      = (channel - wf.om) * 100.;
+  wf.id      = rdmc_amanda_strtoi(args[2] ,RDMC_NA);
+  wf.pa      = rdmc_amanda_strtoi(args[3] ,RDMC_PARENT_NA);
+  wf.ndigi   = atoi(args[4]);
+  wf.t_start = rdmc_amanda_strtof(args[5], RDMC_NA);
+
+  wf.t_bin   = rdmc_amanda_strtof(args[6], RDMC_NA);
+  wf.baseline = rdmc_amanda_strtof(args[7], RDMC_WF_BASELINE_NA);
+
+  if ( nargs < 8 + wf.ndigi)  return RDMC_ILF;          // check # 
+
+  if( wf.ndigi <= 0 || wf.ndigi > RDMC_MAXDIGI )
+    return RDMC_ILF;
+      
+  wf.digi   = malloc(wf.ndigi*sizeof(float));           // fill digit. of waveform
+  for (i = 0; i < wf.ndigi; i++)
+    wf.digi[i] = rdmc_amanda_strtof(args[8+i], RDMC_TDC_NA);
+
+
+  rdmc_add_WF(e,&wf,e->nwf);                            // add waveform to event
+  rdmc_clear_WF(&wf);
+
+  return RDMC_IO_OK;
+} /* rdmc_amanda_WF() */
+
+// pd - end
+
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
+
+
+
diff --git a/RALICE/icepack/iceconvert/f2k_utl.c b/RALICE/icepack/iceconvert/f2k_utl.c
new file mode 100644 (file)
index 0000000..def9195
--- /dev/null
@@ -0,0 +1,875 @@
+
+/* implement functions that help with the f2k format */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "rdmc.h"
+#include "amanda.h"
+#include "f2k.h"
+
+/* copies the string src to dest and removes inline coments, leading blanks */
+/* returns the number of characters copied */
+static int rdmc_f2k_strcleancpy(char *dest, char *src);
+
+
+
+/****************************************************************************/
+int rdmc_f2k_dummy_parser(mcfile *fp, array *a, mevt *e, void *misc){ 
+  return RDMC_IO_OK;
+}
+/****************************************************************************/
+int rdmc_f2k_dummy_event_writer(const mcfile *fp, const array *a, const mevt *e){ 
+  return RDMC_IO_OK;
+}
+/****************************************************************************/
+
+/****************************************************************************/
+/* returns 1 if the format version is supportet */
+int rdmc_is_f2000_supported(int major, int minor){
+  static struct {
+    int major ;
+    int minor ;
+  } supportet[] = 
+    { {1,1} ,{1,2} , {2004,1},  {0,0} };
+  int i=0;
+
+  while (( supportet[i].major != 0) && ( supportet[i].minor != 0)){
+    if (supportet[i].major == major){
+      if (supportet[i].minor == minor){
+       return 1;
+      }
+    }
+    i++;
+  }
+  return 0;
+}
+
+/* stores specific error information int f2k file pointer for print */
+void rdmc_f2k_errorlog(mcfile *fp){
+  rdmc_f2k_buffer_t *f2k_buff = fp->info.f2000.f2k_buffer;
+  int iline= f2k_buff->iline;
+  char *token_pt = f2k_buff->line_pt[iline];
+  char *target_pt = fp->info.f2000.parse_line;
+  char *end_pt=NULL;
+
+  if (*target_pt)
+    return; /* already one error */
+  *target_pt='\0';
+  fp->info.f2000.errline  = fp->fpos - f2k_buff->lines + iline +1;
+  /* try to recover the tokenized line  arghhhh */
+  if (iline+1 >= f2k_buff->lines) 
+    end_pt = &(f2k_buff->buff[f2k_buff->used-1]);
+  else
+    end_pt = f2k_buff->line_pt[iline+1];
+  while (token_pt < end_pt ){
+    if(*token_pt == '\0')
+      *target_pt=' ';
+    else
+      *target_pt = *token_pt;
+    target_pt++;      
+    token_pt++;
+  }
+  *target_pt = '\0';
+  return;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/* text buffer functions *********************/
+void rdmc_push_f2k_buffer(rdmc_f2k_buffer_t *b, char *s, 
+                         const f2000_line_t * type_def){
+  int nnew;
+
+  /* check the size and increase it if necessary */
+  while ( (b->used + RDMC_MAXLINE + 1) >= b->ntot){
+    register int i;
+    long int pedestal;
+    char* bsave = b->buff; /* is needed to save the former location */
+
+#if 0
+    fprintf(stderr,"bused=%i lused=%i btot=%i ltot=%i %.10s\n",b->used, b->lines, b->ntot,b->lines_tot,s); 
+#endif
+
+    b->ntot += F2K_BUFFERSIZE;
+    b->buff = realloc(b->buff,b->ntot*sizeof(char));
+
+    /* now correct the line_pointer pointers */
+    pedestal = (long int ) (b->buff - bsave); /* amount buffer was mooved */
+#if 0
+    fprintf(stderr," %p %p %p %i %p\n",bsave,b->buff,b->line_pt[0],pedestal,b->line_pt[0]+pedestal);
+#endif
+    for(i=0 ; i< b-> lines; i++){
+       b->line_pt[i] += pedestal; /* only line pointers have to be cotrected */
+
+    }
+  }
+
+  while( (b->lines+1) >= b->lines_tot){
+    b->lines_tot += F2K_LINE_BUFFERSIZE;
+    b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
+    b->type_def = realloc(b->type_def
+                         ,b->lines_tot*sizeof(const f2000_line_t *));
+  }
+
+  /* copy the string */
+    nnew = rdmc_f2k_strcleancpy(&(b->buff[b->used]),s);
+    if(nnew){
+      b->type_def[b->lines] = type_def;
+      b->line_pt[b->lines] = &(b->buff[b->used]);
+      b->used += nnew;
+      b->lines += 1;
+      b->line_pt[b->lines] = NULL; /* flag the last line to NULL */
+    }
+}
+
+void rdmc_init_f2k_buffer(rdmc_f2k_buffer_t *b){
+  b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
+  b->ntot = b->lines_tot = 0;
+  rdmc_reset_f2k_buffer(b);
+}
+
+void rdmc_reset_f2k_buffer(rdmc_f2k_buffer_t *b){
+  b->used = b->lines = b->iline = 0;
+
+  b->ntot=F2K_BUFFERSIZE;
+  b->buff = realloc(b->buff,b->ntot*sizeof(char));
+
+  b->lines_tot = F2K_LINE_BUFFERSIZE;
+  b->line_pt = realloc(b->line_pt,b->lines_tot*sizeof(char *));
+  b->type_def = realloc(b->type_def,b->lines_tot*sizeof(f2000_line_t *));
+
+}
+
+void rdmc_clear_f2k_buffer(rdmc_f2k_buffer_t *b){
+  b->used = b->lines = b->iline = 0;
+}
+
+void rdmc_unlink_f2k_buffer(rdmc_f2k_buffer_t *b){
+  free(b->buff);
+  free(b->type_def);
+  free(b->line_pt);
+  b->ntot = b->lines_tot = 0;
+  b->buff = NULL; b->line_pt = NULL ; b->type_def = NULL;
+}
+
+/*********************************************/
+static int rdmc_f2k_strcleancpy(char *dest, char *src){
+  int ncp=0;                           /* number of chars copied to dest */
+  char *spt=src;
+  char *dpt=dest;
+  int leading_space=1;              /* flag to mark the begining of parsing */
+
+  /* copy the string */
+  while (*spt) {
+    if (leading_space){ /* scip leading spaces */ 
+      if (isspace(*spt)){
+       ++(spt);
+       continue;
+      }else{
+       leading_space = 0;
+      }
+    }
+    /* now we are pointing to the first non-white */
+    /* kill inline comments */
+    *dpt = *spt;
+    ++(dpt);
+    ++(spt);
+    ++ncp;
+  }
+  
+  /* append a \0 terminator */
+  *dpt='\0';
+  ++ncp;
+  return ncp;
+}
+
+
+/***************************************************************************/
+
+/**********************************************************************
+ * scans a nonempty line into tokens
+ **********************************************************************/
+char ** rdmc_f2k_tokenize(char *s, int *nargs) {
+  static char ** f2k_tokens = NULL; /* buffer for tokens */
+  static int f2k_maxtoken =0;       /* buffer for tokens */
+  const char delim[]=" \t\n";
+  char *tok_pt;
+  
+  *nargs=0;
+  tok_pt = strtok(s,delim); /* find first non-whitespace char */
+  while (tok_pt){
+    if (*nargs >= f2k_maxtoken ){
+      f2k_maxtoken += RDMC_MAXTOKEN_PER_LINE + 1; 
+      f2k_tokens = realloc(f2k_tokens,f2k_maxtoken*sizeof(char *));
+    }
+    f2k_tokens[*nargs] = tok_pt;
+    *nargs += 1;
+    tok_pt = strtok(NULL,delim); /* find first non-whitespace char */
+  }
+  f2k_tokens[*nargs + 1] = NULL;
+
+  return f2k_tokens;
+} /* amanda_tokenize() */
+
+
+
+/****************************************************************************/
+/****************************************************************************/
+/** string conversion functions                    */
+
+/****************************************************************************
+ * return the OM id, with the experiment prefix (see siegmund format 
+ *  description about these ids)
+ ****************************************************************************/
+int rdmc_amanda_iomid(const char *str,int array_id){
+  return rdmc_amanda_ipmtid(str) 
+    + 100000*(array_id / 100);
+}
+
+const char * rdmc_amanda_somid(int id){
+  return rdmc_amanda_spmtid(id);
+}
+
+/****************************************************************************
+ * return the OM id, with the experiment prefix (see siegmund format 
+ *  description about these ids)
+ ****************************************************************************/
+const char *rdmc_amanda_spmtid(int type)
+{
+  int pmtid, sphereid, dataid;
+  int i;
+  static char typestring[RDMC_MAXTOKENLENGTH];
+  char *sphere, *pmt, *data;
+
+  pmtid = type%100;
+  dataid = (type/100)%100;
+  sphereid = (type/10000)%10;
+
+  pmt = "std";
+  for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
+    if (rdmc_pmt_idtable[i].id == pmtid) {
+      pmt =  rdmc_pmt_idtable[i].name;
+      break;
+    }
+
+  sphere = "std";
+  for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
+    if (rdmc_sphere_idtable[i].id == sphereid) {
+      sphere =  rdmc_sphere_idtable[i].name;
+      break;
+    }
+
+  data = "std";
+  for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
+    if (rdmc_datatrans_idtable[i].id == dataid) {
+      data =  rdmc_datatrans_idtable[i].name;
+      break;
+    }
+
+  sprintf(typestring, "%s-%s-%s", pmt, sphere, data);
+
+  return typestring;
+
+} /* rdmc_amanda_spmtid */
+
+
+/****************************************************************************
+ * return the OM id, without the experiment prefix (see siegmund format 
+ *  description about these ids)
+ ****************************************************************************/
+int rdmc_amanda_ipmtid(const char *str)
+{
+  char *tok;
+  char *c;
+  int pmtid, dataid, sphereid;
+  int i;
+  char s1[RDMC_MAXTOKENLENGTH];
+
+  strcpy(s1,str);
+
+  tok = strtok(s1, "-");
+  if (tok == NULL) return 0;
+  for (c=tok ; *c ; c++)
+    *c=tolower((int) *c);
+
+  pmtid = 0;
+  for (i = 0; rdmc_pmt_idtable[i].name != NULL; i++)
+    if (strcmp(rdmc_pmt_idtable[i].name, tok) == 0) {
+      pmtid =  rdmc_pmt_idtable[i].id;
+      break;
+    }
+  
+  tok = strtok(NULL, "-");
+  if (tok == NULL) return pmtid;
+  for (c=tok ; *c ; c++)
+    *c=tolower((int) *c);
+  
+  sphereid = 0;
+  for (i = 0; rdmc_sphere_idtable[i].name != NULL; i++)
+    if (strcmp(rdmc_sphere_idtable[i].name, tok) == 0) {
+      sphereid =  rdmc_sphere_idtable[i].id;
+      break;
+    }
+
+  tok = strtok(NULL, "-");
+  if (tok == NULL) return 10000*sphereid + pmtid;
+  for (c=tok ; *c ; c++)
+    *c=tolower((int) *c);
+
+  dataid = 0;
+  for (i = 0; rdmc_datatrans_idtable[i].name != NULL; i++)
+    if (strcmp(rdmc_datatrans_idtable[i].name, tok) == 0) {
+      dataid =  rdmc_datatrans_idtable[i].id;
+      break;
+    }
+  
+  return 10000*sphereid + 100*dataid + pmtid;
+
+} /* rdmc_amanda_ipmtid() */
+
+/****************************************************************************
+ * build a string containing the Detector name, or "Neutrino_telescope" if
+ * unknown
+ ****************************************************************************/
+
+const char *rdmc_amanda_sdet(int geoid)
+{
+  int i;
+  for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
+    if (rdmc_detector_idtable[i].id == geoid) 
+      return  rdmc_detector_idtable[i].name;
+  return rdmc_detector_idtable[0].name;
+} /* rdmc_amanda_sdet() */
+
+int rdmc_amanda_idet(const char *detnam)
+{
+  int i;
+  char tmp_detnam[RDMC_MAXTOKENLENGTH];
+  char *c;
+  
+  strncpy(tmp_detnam,detnam,RDMC_MAXTOKENLENGTH-1);
+  tmp_detnam[RDMC_MAXTOKENLENGTH-1]='\0';
+
+  c=tmp_detnam;
+  while(*c){
+    *c = tolower((int) *c);
+    c++;
+  }
+
+  for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
+    if (strcmp(rdmc_detector_idtable[i].name, tmp_detnam) == 0)
+      return  rdmc_detector_idtable[i].id;
+
+  /* maybe, we find a substring? */
+  for (i = 0; rdmc_detector_idtable[i].name != NULL; i++)
+    if (strstr(rdmc_detector_idtable[i].name, tmp_detnam) != NULL)
+      return  rdmc_detector_idtable[i].id;
+  return rdmc_detector_idtable[0].id;
+
+} /* rdmc_amanda_detid() */
+
+
+/****************************************************************************
+ * build a string containing the particle name
+ ****************************************************************************/
+const char *rdmc_amanda_spartid(int id)
+{
+  int i;
+  static char a_primary[]="Axxx";
+  static char z_primary[]="Zxxx";
+
+  if ((id>=Z_PRIMARY) && (id < (Z_PRIMARY+200))){ /* primary Zxx */
+    int idd=id-Z_PRIMARY;
+#if 0
+    if(idd <10)
+      sprintf(z_primary,"Z00%1i",idd);
+    else if(idd <100)
+      sprintf(z_primary,"Z0%2i",idd);
+    else
+      sprintf(z_primary,"Z%3i",idd);
+#else
+      sprintf(z_primary,"Z%i",idd);
+#endif
+
+    return z_primary;
+  }else if ((id>=A_PRIMARY) && (id < A_PRIMARY+500)){ /* primary Axxx undocumented !! */ 
+    int idd=id-A_PRIMARY;
+#if 0
+    if(idd <10)
+      sprintf(a_primary,"A00%1i",idd);
+    else if(idd <100)
+      sprintf(a_primary,"A0%2i",idd);
+    else
+      sprintf(a_primary,"A%3i",idd);
+#else
+    sprintf(a_primary,"A%i",idd);
+#endif
+    return a_primary;
+  }
+
+  for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
+    if (rdmc_particle_idtable[i].id == id) 
+      return  rdmc_particle_idtable[i].name;
+
+  return rdmc_amanda_spartid(0); /* return unknown */
+
+} /* rdmc_amanda_spartid */
+
+
+int rdmc_amanda_ipartid(const char *s)
+{
+  int i;
+  int idd;
+  char name[RDMC_MAXTOKENLENGTH];
+
+  {
+    char *c=name;
+#if 1
+    const char *sp=s;
+    while ( *sp ){
+      *c=tolower((int) *sp);  
+      sp++; 
+      c++;
+    }
+    *(c++)='\0';
+#else
+    strcpy(name,s);
+    for ( ; *c ; c++)
+      *c=tolower(*c);
+#endif
+  }
+
+  for (i = 0; rdmc_particle_idtable[i].name != NULL; i++)
+    if (strcmp(rdmc_particle_idtable[i].name, name) == 0)
+      return  rdmc_particle_idtable[i].id;
+
+  if (name[0] == 'z'){ /* CR primary charge Z */
+    idd=0;
+    if( 1 != sscanf(name,"z%d",&idd))
+      return 0;
+    if (isnan(idd))
+      return 0;
+    idd += Z_PRIMARY;
+    if ( (idd <  Z_PRIMARY) && (idd >=  Z_PRIMARY+200) )
+      return 0;
+    else
+      return idd;
+  }else if (name[0] == 'a'){ /* CR primary mass A */
+    idd=0;
+    if( 1 != sscanf(name,"a%d",&idd))
+      return 0;
+    if (isnan(idd))
+      return 0;
+    idd += A_PRIMARY;
+    if ( (idd <  A_PRIMARY) && (idd >=  A_PRIMARY+500) )
+      return 0;
+    else
+      return idd;
+  }
+  return 0;
+
+} /* rdmc_amanda_ipartid() */
+
+int rdmc_amanda_mhit_stat(mhit_stat_t *hstat, char *stat_s){
+  char *cpt=stat_s;
+  long int iedges;
+
+  if (*cpt == '\0')
+    return RDMC_IO_OK;
+  if( *cpt == '>'){
+    hstat->tdc_flag = 1;
+    cpt++;
+  }
+  iedges = strtol(cpt, (char **)NULL, 10);
+  if ((iedges == LONG_MIN )|| (iedges == LONG_MAX ))
+    return RDMC_ILF;
+  else
+    hstat->n_tdc_edges = iedges;
+
+  return RDMC_IO_OK;
+}
+
+
+/****************************************************************************/
+/****************************************************************************/
+/** value conversion functions                    */
+/****************************************************************************
+ * make an integer from a string. If "na" or "?" return RDMC_NA
+ ****************************************************************************/
+
+int rdmc_amanda_strtoi(const char *str, int default_na)
+{
+  int r;
+  /* f2000 writes  not na, but ? for NA */   
+  if (strstr(str,"?") != NULL)  
+    return default_na;
+  if (strstr(str,"na") != NULL) /* old rdmc specific value */
+    return default_na;
+  if (strstr(str,"*") !=NULL)
+    return  RDMC_REPEAT_CH;
+  if  (strstr(str,"-inf") !=NULL)
+    return -RDMC_IINFTY;
+  if  (strstr(str,"inf") !=NULL)
+    return RDMC_IINFTY;
+  if  (strstr(str,"N") !=NULL)
+    return RDMC_PARENT_NOISE;
+  if  (strstr(str,"A") !=NULL)
+    return RDMC_PARENT_AFPULS;
+
+
+  r = atoi(str);
+  if (isnan( (float) r ))
+    return  default_na;
+  else
+    return r;
+
+} /* rdmc_amanda_strtoi() */
+
+/****************************************************************************
+ * make a float from a string. If "na" return default_na
+ ****************************************************************************/
+double  rdmc_amanda_strtof(char *str, double default_na)
+{
+  double r;
+  /* f2000 writes  not na, but ? for NA */   
+  if (strstr(str,"?") != NULL)  
+    return  default_na;
+  if (strstr(str,"na") != NULL) /* old rdmc specific value */
+    return default_na;
+  if (strstr(str,"*") !=NULL)
+    return  RDMC_REPEAT_CH;
+  if  (strstr(str,"-inf") !=NULL)
+    return -RDMC_FINFTY;
+  if  (strstr(str,"inf") !=NULL)
+    return RDMC_FINFTY;
+#if 0 /* parent is never a float but an int */
+  if  (strstr(str,"N") !=NULL)
+    return RDMC_PARENT_NOISE;
+  if  (strstr(str,"A") !=NULL)
+    return RDMC_PARENT_AFPULS;
+#endif
+//  r=strtof(str,NULL);
+  r = atof(str);
+  if (isnan( (float) r ))
+    return  default_na;
+  else
+    return r;
+
+} /* rdmc_amanda_strtof() */
+
+/****************************************************************************
+ * make a float to a string.
+ ****************************************************************************/
+char * rdmc_amanda_ftostr(double f, double default_na)
+{
+  static char str[RDMC_MAXTOKENLENGTH];
+  /* f2000 writes  not na, but ? for NA */   
+  if (isnan(f)) return  "NaN";
+  if ( fabs(f - default_na) < 1.e-5 )  
+    return  "?";
+  if (f >= RDMC_FINFTY/2)
+    return "inf";
+  if (f <= -RDMC_FINFTY/2)
+    return "-inf";
+  sprintf(str,"%g",f);
+  return str;
+} /* rdmc_amanda_ftostr() */
+
+/****************************************************************************
+ * make a int to a string. 
+ ****************************************************************************/
+char * rdmc_amanda_itostr(int i, int default_na)
+{
+  static char str[RDMC_MAXTOKENLENGTH];
+  /* f2000 writes  not na, but ? for NA */   
+
+  if (isnan(i)) return  "NaN";
+
+  if (i == default_na)  
+    return  "?";
+  if (i >= RDMC_IINFTY)
+    return "inf";
+  if (i <= -RDMC_IINFTY)
+    return "-inf";
+  sprintf(str,"%i",i);
+  return str;
+
+} /* rdmc_amanda_itostr() */
+
+/****************************************************************************
+ * make a time string sec.nsec. 
+ ****************************************************************************/
+char * rdmc_amanda_itimetostr(int sec, int nsec){
+  static char str[RDMC_MAXTOKENLENGTH];
+  static char s1[RDMC_MAXTOKENLENGTH];
+  static char s2[RDMC_MAXTOKENLENGTH];
+
+  if (isnan(sec)  || (sec<0)   ) 
+    strcpy(s1,"?.");
+  else
+    sprintf(s1,"%i.",sec);
+
+  if (isnan(nsec) || (nsec<0) || (nsec>= 1e9 )   ) 
+    strcpy(s2,"?");
+  else
+    sprintf(s2,"%09i",nsec);
+
+  strcpy(str,s1);
+  strcat(str,s2);
+  return str;
+} /* rdmc_amanda_timestr() */
+
+/* returns 0 on succes */
+int rdmc_amanda_strtimetoi(const char *stime, int *sec, int *nsec){
+  char *spt;
+  int slen;
+  if ( (spt = strchr(stime,'.')) != NULL){
+    
+    *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
+    *nsec = rdmc_amanda_strtoi(spt+1,0); /* test only if a valid number */
+    if (*nsec >0 ){
+      slen = strlen(spt+1) - 9;
+      if (slen < 0){
+       while (slen){
+         *nsec *= 10;
+         slen++;
+       }
+      }
+    }
+  }else{
+    *sec = rdmc_amanda_strtoi(stime,0); /* test only if a valid number */
+    *sec %= 86400 ;  /* seconds of begin of day only is mod(sec,86400)*/
+    *nsec = rdmc_amanda_strtoi("?",0); /* test only if a valid number */
+  }
+  return 0;
+}
+
+int rdmc_f2k_y2k(int year){
+  year = (year > 0 ) ? year : 1970;
+  if (year < 70 )
+    year += 2000;
+  if (year < 100 )
+    year += 1900;
+  return year;
+}
+
+/****************************************************************************
+ * return the orientation (cosinus theta) as a float
+ ****************************************************************************/
+static const struct {
+  char* str;
+  float fori;
+  float upper;
+  float lower;
+} rdmc_updown_table[] = {
+  {"hr", 0.0 , 0.5 , -0.5 },
+  {"HR", 0.0 , 0.5 , -0.5 },
+  {"Hr", 0.0 , 0.5 , -0.5 },
+  {"up", 1.0 , 1.1 , 0.5 },
+  {"UP", 1.0 , 1.1 , 0.5 },
+  {"Up", 1.0 , 1.1 , 0.5 },
+  {"dn", -1.0, -0.5 , -1.1 },
+  {"DN", -1.0, -0.5 , -1.1 },
+  {"Dn", -1.0, -0.5 , -1.1 },
+  {"down", -1.0, -0.5 , -1.1 },
+  {"DOWN", -1.0, -0.5 , -1.1 },
+  {"Down", -1.0, -0.5 , -1.1 },
+  {NULL , 0.0 , 0.0 , 0.0 }
+};
+
+char *rdmc_amanda_sori(float ori){
+  int i;
+  for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
+    if ( (ori  > rdmc_updown_table[i].lower)
+        &&  ( ori  < rdmc_updown_table[i].upper) ){
+      return rdmc_updown_table[i].str;
+    }
+  }
+  return rdmc_updown_table[0].str;
+}
+
+float rdmc_amanda_fori(char *ori)
+{
+  int i;
+  for (i=0 ; rdmc_updown_table[i].str != NULL ; i++ ){
+    if (strcmp(ori,rdmc_updown_table[i].str) == 0) 
+      return rdmc_updown_table[i].fori;
+  }
+  return rdmc_updown_table[0].fori;
+} /* rdmc_amanda_ori() */
+
+
+static const struct {
+  int ival;
+  double val;
+  char *name;
+} rdmc_sp_ftable[] = {
+  { 1, 1.0, "yes" },
+  { 0, 0.0, "no" },
+  { 1, 1.0, "true" },
+  { 0, 0.0, "false" },
+  { RDMC_NA, RDMC_NA, "nan" },
+  { RDMC_NA, RDMC_NA, "na" },
+  { -1,  -1.0 , NULL }
+};
+
+/* catch some special values */
+double rdmc_amanda_sptof(char *str){
+  double r=RDMC_NA;
+  int ir=RDMC_NA,i,slen;
+
+  /* now check for hex numbers */
+  if (strstr(str,"0x") == str){
+    if ( 1 == sscanf(str,"%i",&ir)){
+      r = ir;
+      return r;
+    }
+  }
+
+  /* try to decode directly first */
+  if (sscanf(str,"%lg",&r) == 1){
+    /*    rdmc_msgprintf("%.18g %s %i",r,str,DBL_DIG); */
+    return r;
+  }
+
+  /* make a local copy and tronspose to lower */
+  {  
+    char t[RDMC_MAXTOKENLENGTH];
+    slen = strlen(str);
+    slen = (slen < (RDMC_MAXTOKENLENGTH-1)) ? slen : RDMC_MAXTOKENLENGTH-1;
+    for (i=0 ; i <= slen ; i++){
+      t[i] = tolower((int) str[i]);
+    } 
+    t[slen]='\0';
+    
+    /* check special values */
+    for (i=0; rdmc_sp_ftable[i].name != NULL  ; i++){
+      if( strcmp(rdmc_sp_ftable[i].name,t) == 0){
+       return rdmc_sp_ftable[i].val;
+      }
+    }
+  } /* check for special values */
+
+  /* now try a last decode: */
+  
+  return RDMC_SPECIAL_NA;
+}
+
+
+/* create a string the USES lines for itoken */
+char * rdmc_amanda_uses_to_str(int n_uses, mevt_uses_t *uses, int id){
+  static char *buffer =  NULL;
+  static int bsize = 0;
+  int bused = 0;
+  int i_uses;
+  int char_in_line,token_in_line,last_hid;
+  char tbuff[RDMC_MAXTOKENLENGTH];
+  int cont_flag;
+  int t_len;
+
+#if 1
+  rdmc_sort_uses(uses, n_uses);
+#endif
+
+  /* init the buffer */
+  if (!bsize) {
+    bsize += RDMC_MAXLINE;
+    buffer = malloc(bsize*sizeof(char));
+  }
+  buffer[0] = '\0';
+  bused = char_in_line = token_in_line = 0 ;
+  tbuff[0] = '\0';
+  last_hid =  RDMC_NA; /* the last seen OM */
+  cont_flag=0;
+
+  /* now loop and look */
+  for (i_uses = 0 ; i_uses < n_uses ; i_uses++){
+    if ( uses[i_uses].useid == id ){ /*** ahh there is one ***/
+
+      /* check buffersize  large enough */
+      /* 2* -> save space for USES and \n */
+      while ( (bused + 2*RDMC_MAXTOKENLENGTH) > bsize){ 
+       bsize += RDMC_MAXLINE;
+       buffer =  (char *) realloc(buffer,bsize*sizeof(char));
+      }
+
+      /* check the current lenght */
+      if ( ( (char_in_line+RDMC_MAXTOKENLENGTH) >= F2000_MAXLINE )
+          || (token_in_line >= RDMC_MAXTOKEN_PER_LINE ) ){
+       if (cont_flag){
+         bused += sprintf(&(buffer[bused]),"-%i",last_hid);
+         cont_flag=0;
+       }
+       bused += sprintf(&(buffer[bused]),"\n");
+       char_in_line = token_in_line = 0 ;
+       last_hid =  RDMC_NA;
+       cont_flag=0;
+      }
+      if (char_in_line == 0 ){
+       char_in_line = strlen("USES");
+       bused += sprintf(&(buffer[bused]),"USES");
+      }
+
+      /* now print this channel */
+      if ((last_hid == RDMC_NA ) ||
+         (uses[i_uses].hitid > last_hid+1 )){
+       if (cont_flag){
+         t_len = sprintf(&(buffer[bused]),"-%i",last_hid);
+         last_hid=RDMC_NA;
+         bused += t_len;
+         char_in_line += t_len;
+         token_in_line++;
+         cont_flag=0;
+       }
+       t_len = sprintf(&(buffer[bused])," %i",uses[i_uses].hitid);
+       last_hid=uses[i_uses].hitid;
+       bused += t_len;
+       char_in_line += t_len;
+       token_in_line++;
+       cont_flag=0;
+      }else{
+       last_hid=uses[i_uses].hitid;
+       cont_flag=1;
+      }
+       
+    } else if ( uses[i_uses].useid > id ){
+#if 1
+      break; /* break to improve speed  since the uses array is sorted */
+#endif
+    }
+  }
+
+  if (bused){
+    if(buffer[bused-1] != '\n'){
+      if (cont_flag){
+       bused += sprintf(&(buffer[bused]),"-%i",last_hid);
+       cont_flag=0;
+      }
+      strcpy(&(buffer[bused]),"\n");
+      bused++;
+    }
+  }
+
+#if 0 /* desireble later */
+  if (buffer[0] == '\0')
+    strcpy(buffer,"USES all\n");
+#endif
+  return buffer;
+}
+
+
+/****************************************************************************
+ ********************************** E O F ***********************************
+ ****************************************************************************/
+
+
+
+
+
+
+
+
+
diff --git a/RALICE/icepack/iceconvert/history.txt b/RALICE/icepack/iceconvert/history.txt
new file mode 100644 (file)
index 0000000..43e30db
--- /dev/null
@@ -0,0 +1,4 @@
+//////////////////////////////////////////////////////////////////////////////////////
+//                                History of updates                                //
+//////////////////////////////////////////////////////////////////////////////////////
+21-apr-2005 NvE First release of the package as a subdirectory of Ralice/icepack.
diff --git a/RALICE/icepack/iceconvert/macros/icef2k.cc b/RALICE/icepack/iceconvert/macros/icef2k.cc
new file mode 100644 (file)
index 0000000..3047fef
--- /dev/null
@@ -0,0 +1,48 @@
+//////////////////////////////////////////////
+// Macro to test new IceF2k conversion class
+//
+// To run this macro in batch, just do
+//
+// root -b -q 
+//
+// NvE 11-mar-2005 Utrecht University
+//////////////////////////////////////////////
+{
+ gSystem->Load("ralice");
+ gSystem->Load("icepack");
+ gSystem->Load("iceconvert");
+
+ // Output file for the event structures
+ TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
+ TTree* otree=new TTree("T","Data of an Amanda run");
+
+ // Limit the number of entries for testing
+ Int_t nentries=5;
+
+ // Print frequency to produce a short summary print every printfreq events
+ Int_t printfreq=1;
+
+ // Split level for the output structures
+ Int_t split=2;
+
+ // Buffer size for the output structures
+ Int_t bsize=32000;
+
+ IceF2k q("run7825.f2k",split,bsize);
+ q.Loop(otree,nentries,printfreq);
+
+ // Select various objects to be added to the output file
+
+ AliObjMatrix* omdb=q.GetOMdbase();
+ if (omdb) omdb->Write();
+
+ AliDevice* fitdefs=q.GetFitdefs();
+ if (fitdefs) fitdefs->Write();
+
+ TDatabasePDG* pdg=q.GetPDG();
+ if (pdg) pdg->Write();
+ // Close output file
+ ofile->Write();
+ ofile->Close();
+}
diff --git a/RALICE/icepack/iceconvert/macros/open.cc b/RALICE/icepack/iceconvert/macros/open.cc
new file mode 100644 (file)
index 0000000..53f2f5c
--- /dev/null
@@ -0,0 +1,36 @@
+////////////////////////////////////////////////////////
+// Macro to attach and open an IceCube event file
+// for interactive investigation.
+//
+// To run this macro, just do
+//
+// root> .x open.cc
+//
+//--- NvE 18-jun-2004 Utrecht University
+/////////////////////////////////////////////
+{
+ gSystem->Load("ralice");
+ gSystem->Load("icepack");
+
+ // Access to the input data
+ TFile* f=new TFile("events.root");
+ TTree* data=(TTree*)f->Get("T");
+
+ // Provide overview of Tree contents
+ cout << endl;
+ data->Print();
+
+ // Define a pointer for an event
+ IceEvent* evt=0;
+
+ // Branch in the tree for the event input
+ data->SetBranchAddress("IceEvent",&evt);
+
+ cout << endl;
+ cout << " *READ* nentries : " << data->GetEntries() << endl;
+ cout << endl;
+
+ cout << " Use data->GetEntry(i) to load the i-th entry." << endl;
+ cout << " The event object is called evt " << endl;
+ cout << endl;
+}
diff --git a/RALICE/icepack/iceconvert/rdmc.c b/RALICE/icepack/iceconvert/rdmc.c
new file mode 100644 (file)
index 0000000..a9fc3a0
--- /dev/null
@@ -0,0 +1,115 @@
+/****************************************************************************/
+/* This is rdmc.c - some routines for reading mc and preprocessed data      */
+/* files in the formats described in format.txt of jk/rw (10.10.93)         */
+/* and in the DUMAND ascii format used by cw                                */
+/****************************************************************************/
+
+char *rdmc_cvsid = 
+"$Header: /net/local/cvsroot/siegmund/rdmc/rdmc.c,v 1.59 2004/04/15 14:45:52 wiebusch Exp $";
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+/////////////////#include <unistd.h>
+
+#include <fcntl.h>
+
+#if defined(OSF1) || defined(AIX) || defined (SunOS)
+#include <errno.h>
+#endif
+
+#include "rdmc.h"
+
+#include "rdmc_local.h"
+
+#ifdef BAIKAL_BIN_F
+#include "baikal.h"
+#endif
+#ifdef AMANDA_ASCII_F
+#include "amanda.h"
+#endif
+#ifdef DUMAND_ASCII_F
+#include "dumand.h"
+#endif
+#ifdef UWI_ASCII_F
+#include "uwi.h"
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0                       /* DEBUG 1 writes some info to stderr */
+#endif
+
+#define PID180 (M_PI/180.)
+
+/****************************************************************************/
+/* write_parameters() simply adds the program name and the parameters to    */
+/* the fp->creator field                                                    */
+/****************************************************************************/
+
+void rdmc_write_parameters(mcfile *fp, int argc,  char **argv, const char *version)
+{
+  int i;
+  char *progname;
+  int linelength = 0;
+
+  progname = strrchr(argv[0],'/');
+  if (progname == NULL) 
+    progname = argv[0];
+  else
+    progname++;
+
+  rdmc_append_comment(&(fp->creator)," ");
+  rdmc_append_comment(&(fp->creator),progname);
+  
+  if (version != NULL) {
+    rdmc_append_comment(&(fp->creator)," (");
+    rdmc_append_comment(&(fp->creator),version);
+    rdmc_append_comment(&(fp->creator),") ");
+  }
+
+  linelength = strlen(progname) + strlen(version) + 5;
+
+  for (i = 1; i < argc; i++) {
+    linelength += strlen(argv[i]) + 1;
+    if (linelength > F2000_MAXLINE - RDMC_MAXTOKENLENGTH) {
+      rdmc_append_comment(&(fp->creator), "\\\n");
+      linelength = 1 + strlen(argv[i]);
+    }
+    rdmc_append_comment(&(fp->creator), " ");
+    rdmc_append_comment(&(fp->creator),argv[i]);
+  }
+
+  rdmc_append_comment(&(fp->creator),"\n");
+
+} /* write_parameters() */
+
+/**********************************************/
+/* appends a comment to a  character field */
+/**********************************************/
+
+void rdmc_append_comment(char **comment, const char *s){
+  if (comment != NULL){ /* it is there at all */
+    if (*comment == NULL) {
+      *comment = (char*)malloc(strlen(s) + 1);
+      strcpy(*comment, s);
+    } else {
+      *comment = (char*)realloc(*comment, strlen(*comment) + strlen(s) + 1);
+      strcat(*comment, s);
+    }
+  }
+}
+
+void rdmc_concat_comment(char **comment, const char *s, const int form){
+  switch(form){
+#if 0     /* not needed */
+  case   DUMAND_ASCII_F  :
+        /* not needed */
+    break;
+#endif
+  default:
+    rdmc_append_comment(comment,"!");
+    break;
+  }
+  rdmc_append_comment(comment,s);
+}
diff --git a/RALICE/icepack/iceconvert/rdmc.h b/RALICE/icepack/iceconvert/rdmc.h
new file mode 100644 (file)
index 0000000..9f0bbbe
--- /dev/null
@@ -0,0 +1,1820 @@
+/****************************************************************************/
+/* This is rdmc.h - some routines for reading mc and preprocessed data      */
+/* Here are the following units used: meter, nanosecond, radian, MeV        */
+/****************************************************************************/
+/* Version: $Header: /net/local/cvsroot/siegmund/rdmc/rdmc.h,v 1.188 2004/04/21 14:37:46 wiebusch Exp $ */
+
+#ifndef _RDMC_H
+#define _RDMC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <limits.h>
+#include <float.h>
+////#include <malloc.h>
+
+#define NEW_USES 0
+#define NEW_MHEAD 1
+
+/*****************************/
+/* general definitions - *******/
+/*****************************/
+
+/* limits */
+
+#define RDMC_MAXCHANNELS 16384
+#define MAXCHANNELS RDMC_MAXCHANNELS /* OBSOLETE */
+
+#define RDMC_MAXLINE 10000  /* maximal input line for the asccii format */
+#define F2000_MAXLINE 10000
+
+#define RDMC_MAXDIGI 4096              /* max. number of digitizations */
+
+#define RDMC_MAXTRIGID  8*(sizeof(long)) /* size of a bitmask */
+
+#define RDMC_MAXTOKENLENGTH 64    /* maximal token length in f2000 */
+  /* #define RDMC_MAXTOKEN_PER_LINE 250*/  /* maximum user words per line */
+#define RDMC_MAXTOKEN_PER_LINE 1000  /* maximum user words per line */
+#define RDMC_MAXUSER_PER_LINE RDMC_MAXTOKEN_PER_LINE  /* maximum user words per line */
+
+
+/* special; values */
+#define RDMC_BIG 1e6                              /* a big value (in meter) */
+#define RDMC_SMALL 1e-9                                    /* a small value */
+#define BIG RDMC_BIG  /*obsolete */
+#define SMALL RDMC_SMALL /* obsolete */
+
+/* some special values converting the f2000 */
+#define RDMC_NA -1          /* "not available" number (a quick hack) */
+#define RDMC_NOT_AV RDMC_NA                  /* an alias, dont use it */
+#define RDMC_PARENT_NA -1 /* this is the parent id for noise hits */
+#define RDMC_PARENT_NOISE -2 /* this is the parent id for noise hits */
+#define RDMC_PARENT_AFPULS -3 /* this is the parent id for afterpulse hits */  
+#define RDMC_REPEAT_CH -2  /* no adc value because it was already given away */
+#define RDMC_TDC_NA  -RDMC_BIG 
+#define RDMC_SPECIAL_NA -RDMC_BIG
+#define RDMC_WF_BASELINE_NA  -RDMC_BIG
+#define RDMC_RSORTAMP_ALL 0
+#define RDMC_RSORTAMP_FIRST 1
+#define RDMC_RSORTAMP_TOT 2
+
+/* special nan values: */
+#define RDMC_LONGI_NA RDMC_BIG   /* ARRAY lattitude */
+#define RDMC_LATTI_NA RDMC_BIG   /* ARRAY longitude */
+#define RDMC_DEPTH_NA RDMC_BIG   /* ARRAY depth longitude */
+
+#define RDMC_DINFTY DBL_MAX         /* double infinity */
+#define RDMC_FINFTY FLT_MAX         /* singkle infinity */
+#define RDMC_IINFTY INT_MAX         /* integer infinity */
+#define RDMC_LINFTY LONG_MAX         /* long integer infinity */
+
+#define RDMC_SMALL_THRESH 0.01
+#define RDMC_DEFAULT_DEPTH -1730.00
+#define RDMC_MIN_ION_ENERGY 100e3
+
+/****** error messages */
+enum RDMC_ERROR_T {
+  RDMC_EOF=EOF,             /* end of file from <stdio.h>, usually -1 */
+  RDMC_ILF=-10 ,                      /* error value: invalid format! */
+  RDMC_UNKNOWN_FORMAT=-11,            /* format could not be detected */
+  RDMC_UNKNOWN_FORMAT_VERSION=-12,  /* format version is not suported */
+  RDMC_INCONSISTENT_GEOMETRY=-13, /*something fishy in the file header*/
+  RDMC_LINE_NOT_PARSED=-14,              /* input line is not  parsed */
+  RDMC_TOO_MANY_CHANNELS=-15,     /* OM number larger RDMC_MAXCHANNEL */
+  RDMC_HEADERTAG_NOTFOUND=-16,    /* the current mevt special was not */
+                                           /*   defined in the header */
+  RDMC_EVENT_NOT_RECOGNIZED=-17,  /* the f2k block was not identified */
+  RDMC_EE_NOT_RECOGNIZED=-18,   /* the end of an f2k block  not found */
+  RDMC_LINE_EMPTY=-19, /* the line is only white (not really an error */
+  RDMC_LIBRARY_ERROR=-20,  /* a programming error in the rdmc library */
+  RDMC_IO_OK=0                                    /* everythings fine */
+};
+
+/***** format ids */
+#define BAIKAL_BIN_F 0          /* format id for the baikal-like bin format */
+#define DUMAND_ASCII_F 1      /* format id for the dumand-like ASCII format */
+#define UWI_ASCII_F 2      /* format id for the ASCII used by Jacobsen etal */
+#define STOCKHOLM_BIN_F 3     /* format id for swedish amanda binary format */
+#define AMANDA_ASCII_F 4        /* the proposed AMANDA format (aka "F2000") */
+#define F2000_F AMANDA_ASCII_F
+#define RDMC_DEFAULT_ASCII_F  AMANDA_ASCII_F
+
+/****** Current implemented format versions ********/
+
+#define DUMAND_ASCII_VERSION  -7                /* ASCII version format id */
+#define UWI_ASCII_VERSION 3
+#define AMANDA_ASCII_VERSION 2004      /* minor number; major expected to be 1 */
+#define AMANDA_ASCII_MINOR 1        /* minor number; major expected to be 1 */
+
+/* baikal format dialects */
+#define BAIKAL_MOS -1                       /* id for the moscow bin format */
+#define BAIKAL_OLD 0                   /* id for the old zeuthen bin format */
+#define BAIKAL_NEW 1                   /* id for the new zeuthen bin format */
+
+#define DEFAULT_UWI_GEO_FILE "amanda.geo"
+#define DEFAULT_UWI_GEO_FILE_ENV "RDMC_UWI_GEO_FILE"
+#ifdef RDMC_DIRTY_AMANDA_ADC /* very ugly */
+#define UWI_CHANNELS_PER_PE 120.         /* number of adc channels per p.e. */
+                                                   /* (uwi format) */
+#else
+#define UWI_CHANNELS_PER_PE 1.         /* number of adc channels per p.e. */
+#endif
+/* some conventions */
+
+#define RDMC_READ_MODE 0
+#define RDMC_WRITE_MODE 1
+
+/****** event types */
+enum RDMC_EVENT_T {
+  RDMC_EVENT_MUON=1, 
+  RDMC_EVENT_HEADER_PREF,
+  RDMC_EVENT_HEADER,
+  RDMC_EVENT_FOOT
+};
+
+  /* detector ids */
+enum RDMC_GEO_ID_T {
+ AMANDA = 2000,
+ AMANDA_A = 2004,
+ AMANDA_B_4 = 2006,
+ AMANDA_B_10 = 2007,
+ AMANDA_B_11 = 2008,
+ AMANDA_B_13 = 2009,
+ AMANDA_II = 2010,
+ AMANDA_KM3 = 2099,
+ JULIA = 6091,
+ BAIKAL = 1000,
+ NT_36 = 1003 ,                    /* array id for the baikal = telescope */
+ NT_36s = 1004,
+ NT_72 = 1005,
+ NT_96 = 1006,
+ NT_144 = 1007,
+ NT_192 = 1008,
+ NT_200 = 1099
+};
+
+/* om ids */
+#define QUASAR 1000000                                     /* Quasar pmt id */
+#define STD_AMANDA_A_OM 2030030
+#define STD_AMANDA_B_OM 2020021
+#define STD_AMANDA_B_10_OM 2020121
+#define AMANDA_HYBRID  2020221
+#define RDMC_DEFAULT_OM STD_AMANDA_B_OM
+
+/* calibration status */
+  /* the entry array_calib_t is a bitmask of these */
+#define RDMC_CALIB_TDC 0x01
+#define RDMC_CALIB_ADC 0x02
+#define RDMC_CALIB_TOT 0x04
+#define RDMC_CALIB_GEO 0x08
+
+
+/* particle ids */
+#define GAMMA 1
+#define E_PLUS 2
+#define E_MINUS 3
+#define NU 4
+#define MUON_PLUS 5                                /* particle id for a mu+ */
+#define MUON_MINUS 6                               /* particle id for a mu- */
+#define MUON MUON_PLUS /* default: mu+ */
+#define PI_0 7
+#define PI_PLUS 8
+#define PI_MINUS 9
+#define P_PLUS 14
+#define P_MINUS 15
+#define TAU_PLUS 33 
+#define TAU_MINUS 34
+#define TAU TAU_PLUS 
+
+#define NU_EL 201
+#define NU_MU 202
+#define NU_TAU 203
+#define NU_EL_BAR 204
+#define NU_MU_BAR 205
+#define NU_TAU_BAR 206
+
+#define BREMS 1001                        /* particle id for bremsstrahlung */
+#define DELTAE 1002                       /* delta electron */
+#define PAIRPROD 1003                     /* pair production */
+#define NUCL_INT 1004                     /* nuclear interaction */
+#define MU_PAIR 1005                      /* muon pair */
+#define HADRONS 1006
+#define FIBERLASER 2100       /* Fiber laser (Baikal or Amanda calib laser) */
+#define N2LASER 2101                      /* N2 laser firing in water or ice */
+#define YAGLASER 2201                    /* YAG laser firing in water or ice */
+#define Z_PRIMARY 3000                /* CR primary with Z xxx start here */
+#define A_PRIMARY 3500                /* CR primary with A xxx start here */
+
+/* which command to use for retrieving of remote files */
+#define ALLOW_REMOTE /* allow writing/reading of remote files */
+#define RSH_CMD_ENV "RDMC_RSH"   /* name of the environment variable */
+
+/* sorting tags which are allowed by rdmc_sort_hits */
+enum RDMC_SORT_T{
+  RDMC_NO_SORT=0,                                     /* no hit sorting */
+  RDMC_CH_SORT=1,                              /* sort hits by channels */
+  RDMC_TM_SORT=2,                              /* sort hits by hit time */
+  RDMC_CZ_SORT=3,                        /* sort hits by hit channel depth */
+  RDMC_ID_SORT=4,                        /* sort hits by mhit-id */
+  RDMC_MT_SORT=5                        /* sort hits by mt-id */
+};
+
+  /* types of possible MCinfo inquireies */
+  /* used by rdmc_which_gen in rdmc_genutl.c */
+
+enum RDMC_GENINFO_T {
+  MOST_HITS_MUON=1 /* muon responsible for  most hits in the event */
+  , HIGHEST_ENERGY_MUON /* the most energetic muon */
+  , CLOSEST_MUON  /* the closest track to the detector centre */
+  , FIRST_HIT_MUON  /* the muon which makes the first hit */
+  , MOST_HITS_SHOWER /* shower responsible for  most hits in the event */
+  , HIGHEST_ENERGY_SHOWER /* the most energetic shower  */
+  , ANY_PRIMARY    /* the first Primary in the file */
+  , CR_PRIMARY        /* the  CR PRIMARY */
+  , NEUTRINO_PRIMARY  /* the first(index) neutrino primary in event */
+};
+
+ /********************************** data structures *************************/
+
+
+
+/************** structures for the maintainance of different formats ********/
+
+typedef struct {
+  char parse_line[RDMC_MAXLINE];  /* line buffer during I/O f2k */
+  int unread;                       /* this flag is 1 if the line is unread */
+  int errline;                  /* file line where a parse error occurs */
+  int nolex; /* if on, the  event is not parsed and can  not be used further */
+  struct rdmc_f2k_buffer_s *f2k_buffer; /* this is defined in f2k.h */
+} f2000_fp_t;
+
+typedef struct {
+  int mc_id;                         /* mc id character */
+              /* 'U' = unknown, 'D' =data, 'M' = MC, 'G' = event generator */
+  char mc_vers[RDMC_MAXLINE];                        /* mc program version */
+  int igtrack;                                        /* presently unused -1*/
+  int igen;                                 /* id for the generator program */
+  int igeo;                           /* identifier for expoeriment type    */
+  int daswrun;                           /* Random generator seed           */
+  time_t time;                               /* mc creation date (obsolete) */
+  int nrun;                                 /*run number */
+} dumand_fp_t;
+
+typedef struct {
+  int mc_id;                         /* mc id character */
+              /* 'U' = unknown, 'D' =data, 'M' = MC, 'G' = event generator */
+  char mc_vers[RDMC_MAXLINE];                        /* mc program version */
+} uwi_fp_t;
+
+typedef struct {
+  int mc;                                          /* 0 - data file, 1 - mc */
+  int swap;                       /* 1 - Bytes are swapped, 0 - not swapped */
+  int fortran_recs;                    /* was it a formatted fortran file? */
+  int nw_rec_arr;    /* number of words in reco sub header (baikal_bin only)*/
+  int nw_rec_evt;   /* number of words in reco sub record  (baikal_bin only)*/
+  int rec_vers;                    /* reco program version (baikal_bin only)*/
+  int min_vers;          /* minimization procedure applied (baikal_bin only)*/
+  int enr;                              /* current event number OBSOLETE */
+  int mc_id;                         /* mc id character */
+              /* 'U' = unknown, 'D' =data, 'M' = MC, 'G' = event generator */
+  char mc_vers[RDMC_MAXLINE];                        /* mc program version */
+  int igtrack;                                        /* presently unused -1*/
+  int igen;                                 /* id for the generator program */
+  time_t time;                               /* mc creation date (obsolete) */
+  int nrun;                                 /*run number */
+} baikal_fp_t;
+
+/* a union type for the mcfile structure */
+typedef union {
+    f2000_fp_t f2000; 
+    dumand_fp_t dum; 
+    uwi_fp_t uwi; 
+    baikal_fp_t bai; 
+} rdmc_special_format_info_t;
+
+
+typedef struct {
+  FILE *fp;                                     /* this is the file pointer */
+  int mode;                             /* read or write mode */
+  int format;                         /* Format: baikal/siegmund/amanda/... */
+  int fpos;                           /* file position (line nr or byte nr) */
+  int fmajor;                           /* format version */
+  int fminor;                                       /* minor version number */
+  int zipped;                                /* == 1 if the file was zipped */
+  int errline;                  /* source line where an format error occurs */
+  char last_line[RDMC_MAXLINE];     /* buffer for the last input line */
+                                      /* set to [0]=0 if nothing inside */
+  int sloppy;          /* sloppy access to data -> force events after error */
+  char *creator;            /* string that points to the History lines */
+  char *comment;           /* string that points to the top comment lines */
+  rdmc_special_format_info_t info;  /* format specific stuff */
+} mcfile;
+
+/* now the event header structures  for CALIBRATION */
+
+typedef struct {
+  float beta_t;                             /* TDC resolution, nsec/channel */
+  float t_0;                                            /* time shift, nsec */
+  float alpha_t;    /* amplitude dependend time calibration, nsec*sqrt(ADC) */
+  float ped;                                /* amplitude pedestal, channels */
+  float beta_a;                             /* ADC resolution, p.e./channel */
+  float kappa;                              /* amplitude nonlinearity, p.e. */
+  float ped_tot;                                 /* tot  pedestal, channels */
+  float beta_tot;                           /* TOT resolution, p.e./channel */
+  float kappa_tot;                               /* tot  nonlinearity, p.e. */
+  int flag;        /* != 0 if this is a valid calib entry -> RDMC_CALIB_... */
+} array_calib_t;
+
+typedef struct {
+  char utc_src[RDMC_MAXTOKENLENGTH];  /* source of this calibration */
+  int secs;                                  /* time correction to.be.  */
+  int nsecs;                             /* applied to the event time */
+} array_calib_utc_t;  
+
+typedef struct {
+  int geo;                                    /* 1 if calibration was done */
+  int adc;                                    /* 1 if calibration was done */
+  int tdc;                                    /* 1 if calibration was done */
+  int tot;                                    /* 1 if calibration was done */
+  int utc;                                    /* 1 if calibration was done */
+} array_calib_stat_t;                         /* 1 if calibration was done */
+
+/* now various header definitions */
+
+typedef struct {
+  int id;
+  char tag[RDMC_MAXTOKENLENGTH]; 
+  int nwords;
+  int npars;
+#if !NEW_USES
+  char words[RDMC_MAXTOKEN_PER_LINE][RDMC_MAXTOKENLENGTH];
+  char pars[RDMC_MAXTOKEN_PER_LINE][RDMC_MAXTOKENLENGTH];
+#else
+  char *words[RDMC_MAXTOKENLENGTH];
+  char *pars[RDMC_MAXTOKENLENGTH];
+#endif
+} array_hdef_t;
+
+
+typedef struct {
+  int id;                                                    /* geometry id */
+  int nch;                                            /* number of channels */
+  int nstr;                                            /* number of strings */
+  float longitude;                /* detector location longitude, [degrees] */
+  float lattitude;                /* detector location lattitude, [degrees] */
+  float depth;                                       /* detector depth, [m] */
+  int nrun;                                                   /* run number */
+  /* geometry follows */
+  int str[RDMC_MAXCHANNELS];                               /* string number */
+  int clust[RDMC_MAXCHANNELS];                            /* channel number */
+  float x[RDMC_MAXCHANNELS];                      /* x coordinate in meters */
+  float y[RDMC_MAXCHANNELS];                      /* y coordinate in meters */
+  float z[RDMC_MAXCHANNELS];                      /* z coordinate in meters */
+  float costh[RDMC_MAXCHANNELS];  /* cos theta of the channel (+1=up/-1=dn) */
+  int type[RDMC_MAXCHANNELS];                                   /* OM type */
+  int serial[RDMC_MAXCHANNELS];                 /* serial number of channel */
+  float thresh[RDMC_MAXCHANNELS];                  /* thresholds of all pmt */
+  float sensit[RDMC_MAXCHANNELS];               /* sensitivities of all pmt */
+  /* values of the dynamic allocation */
+  int n_trigger;                                   /* number of triggers */
+  int n_user;                                /* number of userdef lines */
+  int n_fit;                                /* number of fit def lines */
+  int n_stat;                 /* number of status defs */
+  int n_mcinfo;                                   /* number of mcinfo's */
+  /* time of the  file */
+  time_t tbegin;                                       /* mc creation date */
+  time_t tend;                                          /* mc  end date */
+  /* calibration */
+  array_calib_stat_t is_calib;          /* which calibrations have been done*/
+  array_calib_t cal[RDMC_MAXCHANNELS];        /* time/amplitude calibration */
+  array_calib_utc_t cal_utc;            /* utc calibration */
+  /* trigger */
+  array_hdef_t *def_trig;
+  /* user */
+  array_hdef_t  *def_user;     /* NULL or an array of user line defs */
+  /* fits */
+  array_hdef_t  *def_fit;        /* NULL or an array of fit line defs */
+  /* status ==  housekeeping */
+  array_hdef_t *def_stat;           /* see above */
+  /* mcinfo, still a dummy */
+  array_hdef_t *def_mcinfo;   /* mcinfos types */
+ /* uniqe array id attached by init and clear */
+  unsigned long int array_id; 
+  /* comments */
+  char *comment;          /* comment line: a '\0' terminated string or NULL */
+  void *tmp;             /* a stack to hold anything */
+} array;               /* geometric and technic array info of the telescope */
+
+#if NEW_MHEAD
+  /* now the new arry structure */
+typedef struct {
+  int id;                                         /* unique channel id */
+  int type;                                    /* type of this channel */
+  float thresh;                             /* diskriminator threshold */
+  array_calib_t cal;            /* time/amplitude calibration constants*/
+} mch_def_t;
+
+
+typedef struct {
+  int id;                                                  /* channel id */
+  int type;                                                   /* OM type */
+  int serial;                                     /* serial number of OM */
+  int str;                                              /* string number */ 
+  int clust;                                      /* OM number in string */
+  int x;                                       /* x coordinate in meters */
+  int y;                                       /* y coordinate in meters */
+  int z;                                       /* z coordinate in meters */
+  int costh;                    /* cos theta  orientation  (+1=up/-1=dn) */
+  int sensit;                             /* rel. sensitivity of the pmt */
+  int n_ch;                                 /* number of readout channels */
+  mch_def_t *ch;                         /* field of nch readoutchannels */
+} mom_def_t;
+
+typedef struct {
+  unsigned long int array_id;   /* uniqe array id created by init and clear */
+  int id;                                                    /* geometry id */
+  float longitude;                /* detector location longitude, [degrees] */
+  float lattitude;                /* detector location lattitude, [degrees] */
+  float depth;                                       /* detector depth, [m] */
+  int nstr;                                            /* number of strings */
+  int n_om;                                                  /* number of OM */
+  int n_trigger;                                      /* number of triggers */
+  int n_user;                                         /* number of userdef  */
+  int n_fit;                                     /* number of fit def lines */
+  int n_stat;                                      /* number of status defs */
+  int n_mcinfo;                                       /* number of mcinfo's */
+  mom_def_t *om;                                       /* field of nom OM's */
+  array_calib_stat_t is_calib;          /* which calibrations have been done*/
+  array_calib_utc_t cal_utc;                             /* utc calibration */
+  array_hdef_t *def_trig;                           /* n_trigger triggerdefs*/
+  array_hdef_t  *def_user;                             /*  n_user line defs */
+  array_hdef_t  *def_fit;                                /*  n_fit fit defs */
+  array_hdef_t *def_stat;                               /*  n_stat fit defs */
+  array_hdef_t *def_mcinfo;                           /*  n_mcinfo fit defs */
+  char *comment;          /* comment line: a '\0' terminated string or NULL */
+  void *tmp;             /* a stack to hold anything */
+} mhead_t;           /* structure for the file header/definitions  */
+
+#endif
+
+/* now the event related structures */
+
+typedef struct {
+#if NEW_USES
+  int nuses; /* number of hits */
+  int *id;   /* the hit id */
+#else
+  int hitid;  /* id of the hit */
+  int useid; /* id of the fit or the trigger */
+#endif
+} mevt_uses_t;
+
+
+
+typedef struct {
+  int id;  /* identifier/index of e.g. the trigger */
+  int nval;
+  float val[RDMC_MAXTOKEN_PER_LINE];  /*the values defined e.g. in the TRIG_DEF line */
+#if NEW_USES
+  mevt_uses_t uses;
+#endif
+} mevt_special_t;
+
+typedef struct {
+  int id;                                    /* particle id (muon+: id = 5) */
+  float e;                                                /* energy  in MeV */
+  float x,y,z;                           /* parameter of a track point in m */
+  float t;                      /* time in nsec corresponding the point xyz */
+  float costh;                           /* theta cosinus of the muon track */
+  float phi;                                        /* phi value in radians */
+  float px, py, pz;                                   /* direction cosinuus */
+  float length;                  /* length of the track, or BIG if infinity */
+  int nmuon;                        /* obsolete (baikal only) */
+  int parent;                     /*track which is mother of this one */
+  int tag;                       /* unique tag for this track */
+  float weight;                  /* weight of this track */
+  int nuser;                  /* DUMMY presently ! */
+  mevt_special_t *user;                                 /* the user words */
+  char *comment;          /* comment line: a '\0' terminated string or NULL */
+  void *tmp;             /* a stack to hold anything */
+} mtrack;                         /* track info from mc, reconstructed, etc */
+
+typedef struct {
+  int n_tdc_edges;
+  int tdc_flag;
+} mhit_stat_t;
+
+typedef struct {
+  int ch;                                           /* channel number (0,..)*/
+  int str;                                       /* string number (1...str) */
+  float t;                                   /* time in nsec (Leading edge) */
+  float amp;                                   /* amplitude of each channel */
+  float tot;                                  /* time over threshold (nsec) */
+  int mt;                                    /* muon id for this hit (time) */
+  int ma;                               /* muon id for this hit (amplitude) */
+  int id;                                 /* a unique hit id */
+  float weight;                  /* weight of this hit */
+  mhit_stat_t hstat;       /* some status flags for the channel of this hit */
+  int nuser;                  /* DUMMY presently ! */
+  mevt_special_t *user;                                 /* the user words */
+  char *comment;          /* comment line: a '\0' terminated string or NULL */
+  void *tmp;             /* a stack to hold anything */
+} mhit;                                                    /* hit structure */
+
+
+
+typedef struct {
+  int id;                                                 /* a unique WF id */
+  int om;                                                      /* OM number */
+  int ch;                                               /* digitizer number */
+  int pa;                                                      /* parent id */
+  int ndigi;                                       /* numer of digitizations*/
+  float t_start;                                 /* time of 1. digitization */
+  float t_bin;                                        /* width of time bins */
+  float baseline;                            /* running mean of baseline */
+  float *digi;                                   /* amplitude digitizations */
+} waveform;                                           /* waveform structure */
+
+
+typedef struct {
+  int nrun;                                                   /* run number */
+  int enr;                                                  /* event number */
+  int mjd;                                        /* modified julian day  */
+  int secs;                                        /* time in sec after mjd */
+  int nsecs;                                        /* Nanosec part of time */
+  float t_offset;       /* time offset; all hits should be centered by time */
+  float weight;                                     /* weight of this event */
+  int ee;                                /* 1: end of event corectly tagged */
+  int nch;                                     /* number of channels hitted */
+  int nstr;                                     /* number of hitted strings */
+  int nhits;                                              /* number of hits */
+  int nwf;                              /* number of wafeform digitizations */
+  int ntrack;                                        /* number of mc tracks */
+  int nfit;                       /* number of fitted tracks AND fitresults */
+  int nuser;                                      /* number of user blocks  */
+  int nstat;                                     /* number of status blocks */
+  int ntrig;                                          /* number of triggers */
+  int nmcinfo;                           /* number of mcinfo blocks (dummy) */
+#if !NEW_USES
+  int ntrig_uses;                       /* number of uses words for triggers*/
+  int nfit_uses;                           /* number of uses words for fits */
+#endif
+  enum RDMC_SORT_T sort_status;   /* sort status of hits, def: RDMC_NO_SORT */
+  unsigned long int event_id;  /* uniqe event id attached by init and clear */
+  unsigned long trigger;                           /* bitmap of the trigger */
+  unsigned long trigid;                       /* bitmap of the trigger id's */
+  mhit *h;                     /* pointer to all hits (allocated by revt()) */
+  waveform *wf;                    /* pointer to all waveform digitizations */
+  mtrack *gen;                  /* pointer to the generated tracks, or NULL */
+  mtrack *rec;              /* pointer to the reconstructed tracks, or NULL */
+  mevt_special_t *fresult;                       /* the  reco results words */
+  mevt_special_t *user;                                   /* the user words */
+  mevt_special_t *status;                               /* the status words */
+  mevt_special_t *ptrig;                               /* the trigger words */
+  mevt_special_t *mcinfo;                       /* the mcinfo words (dummy) */
+#if !NEW_USES
+  mevt_uses_t *trig_uses;                         /* the trigger uses words */
+  mevt_uses_t *fit_uses;                              /* the fit uses words */
+#endif
+  char *comment;          /* comment line: a '\0' terminated string or NULL */
+  void *tmp;             /* a stack to hold anything */
+} mevt;                 
+
+
+/* structure that holds converions between strings and numbers */
+typedef struct {
+  int id;
+  char *name;
+} rdmc_idtable_t;
+
+/* some tables defined in rdmc_local.c */
+extern const rdmc_idtable_t rdmc_pmt_idtable[];
+extern const rdmc_idtable_t rdmc_sphere_idtable[];
+extern const rdmc_idtable_t rdmc_datatrans_idtable[];
+extern const rdmc_idtable_t rdmc_detector_idtable[];
+extern const rdmc_idtable_t  rdmc_particle_idtable[];
+
+
+/********************************** functions *******************************/
+
+/*###########################################*/
+/***** in rdmc.c ********/
+/*###########################################*/
+void rdmc_write_parameters(mcfile *fp, int argc, char **arg, const char *version);
+        /* add the current program name  to the creator's list (HISTORY) */
+
+void rdmc_append_comment(char **comment, const char *src);
+/* reallocates comment (it must be NULL, or already malloced) */
+/* then appends the string src via strcat */
+
+void rdmc_concat_comment(char **comment, const char *src, const int form);
+/* reallocates comment (it must be NULL, or already malloced) */
+/* then appends the string src via strcat */
+/* prvide with form=mcfile.format, e.g. F2000_F */
+
+
+
+/*###########################################*/
+/***** in rdmc_mcopen.c ********/
+/*###########################################*/
+mcfile *rdmc_mcopen(const char *name, const char *mode, int format); /* opens a mc/data file */
+int rdmc_mcclose(mcfile *fp);              /* closes a mc/data file */
+
+
+/*###########################################*/
+/**** in rdmc_mcfile.c *****/
+/*###########################################*/
+void rdmc_init_mcfile(mcfile *fp, int format, int mode, FILE *ft); /* init */
+void rdmc_free_mcfile(mcfile *fp); /*free */
+int rdmc_mccpfp(const mcfile *src, mcfile *dest);   /* copy run parameters */
+
+
+#if NEW_MHEAD
+/*###########################################*/
+/**** in rdmc_mhead.c *****/
+/*###########################################*/
+void rdmc_init_mhead(mhead_t *a);
+void rdmc_clear_mhead(mhead_t *a);
+void rdmc_free_mhead(mhead_t *a);
+
+/***** now function for the header_def and header_def_par */
+/* functions return 0 on success,  1 else */
+int rdmc_mhead_add_user_def(mhead_t *mh, array_hdef_t *user, int iuse);
+int rdmc_mhead_del_user_def(mhead_t *mh , int iuse);
+int rdmc_mhead_add_stat_def(mhead_t *mh, array_hdef_t *sta, int ista);
+int rdmc_mhead_del_stat_def(mhead_t *mh, int ista);
+int rdmc_mhead_add_fit_def(mhead_t *mh, array_hdef_t *fd, int ifd);
+int rdmc_mhead_del_fit_def(mhead_t *mh, int ifd);
+int rdmc_mhead_add_mcinfo_def(mhead_t *mh, array_hdef_t *mc, int imc);
+int rdmc_mhead_del_mcinfo_def(mhead_t *mh, int imc);
+int rdmc_mhead_add_trigger_def(mhead_t *mh, array_hdef_t *t, int it);
+int rdmc_mhead_del_trigger_def(mhead_t *mh, int it);
+
+int rdmc_mhead_add_mom(mhead_t *mh, mom_def_t *om, int ipos);
+
+
+
+/*###########################################*/
+/**** in rdmc_mom.c *****/
+/*###########################################*/
+void rdmc_init_mom(mom_def_t *ch);
+void rdmc_clear_mom(mom_def_t *ch);
+void rdmc_free_mom(mom_def_t *ch);
+
+
+/*###########################################*/
+/**** in rdmc_mch.c *****/
+/*###########################################*/
+
+void rdmc_init_mch(mch_def_t *ch);
+void rdmc_clear_mch(mch_def_t *ch);
+void rdmc_free_mch(mch_def_t *ch);
+
+#endif
+
+/*###########################################*/
+/**** in rdmc_array_calib.c *****/
+/*###########################################*/
+
+void rdmc_init_array_calib(array_calib_t *c);
+void rdmc_clear_array_calib(array_calib_t *c);
+void rdmc_free_array_calib(array_calib_t *c);
+
+void rdmc_init_array_calib_stat(array_calib_stat_t *cs);
+void rdmc_clear_array_calib_stat(array_calib_stat_t *cs);
+void rdmc_free_array_calib_stat(array_calib_stat_t *cs);
+void rdmc_init_array_calib_utc(array_calib_utc_t *cu);
+void rdmc_clear_array_calib_utc(array_calib_utc_t *cu);
+void rdmc_free_array_calib_utc(array_calib_utc_t *cu);
+
+
+/*###########################################*/
+/**** in array2mhead.c *****/
+/*###########################################*/
+/* target has to be allocated and initilized/cleared (freed memory) */ 
+int rdmc_array2mhead(const array *ar, mhead_t *mh);
+int rdmc_mhead2array(const mhead_t *mh, array *ar);
+
+
+/*###########################################*/
+/**** in rdmc_array.c *****/
+/*###########################################*/
+void rdmc_init_array(array *ar);                               /* structures */
+void rdmc_free_array(array *ar);
+void rdmc_clear_array(array *ar);               /* clear the array structure */
+int rdmc_rarr(mcfile *fp, array *ar);  /* read the array info from the begin */
+int rdmc_warr(mcfile *fp, const array *ar);     /* writes array info to file */
+int rdmc_comp_array(const array *a1, const array *a2);/* compares two geometries */
+/* returns 0 if they are equal */
+/* else it returns the ored result of: */
+#define RDMC_ARRAY_COMP_OK 0x0000            /* all OK*/
+#define RDMC_ARRAY_COMP_HEADER 0x01         
+#define RDMC_ARRAY_COMP_GEO 0x02
+#define RDMC_ARRAY_COMP_OMS 0x04
+#define RDMC_ARRAY_COMP_CALIB 0x08
+#define RDMC_ARRAY_COMP_TRIGGER 0x10
+#define RDMC_ARRAY_COMP_USER 0x20
+#define RDMC_ARRAY_COMP_FIT 0x40
+#define RDMC_ARRAY_COMP_STATUS 0x80
+#define RDMC_ARRAY_COMP_MC 0x100
+
+void rdmc_cp_array(array *out, const array *in);/* copies two geometries */
+
+/***** now function for the header_def and header_def_par */
+/* functions return 0 on success,  1 else */
+int rdmc_array_add_user_def(array *ar, array_hdef_t *user, int iuse);
+int rdmc_array_del_user_def(array *ar , int iuse);
+int rdmc_array_add_stat_def(array *ar, array_hdef_t *sta, int ista);
+int rdmc_array_del_stat_def(array *ar, int ista);
+int rdmc_array_add_fit_def(array *ar, array_hdef_t *fd, int ifd);
+int rdmc_array_del_fit_def(array *ar, int ifd);
+int rdmc_array_add_mcinfo_def(array *ar, array_hdef_t *mc, int imc);
+int rdmc_array_del_mcinfo_def(array *ar, int imc);
+int rdmc_array_add_trigger_def(array *ar, array_hdef_t *t, int it);
+int rdmc_array_del_trigger_def(array *ar, int it);
+
+
+  /* temporary until array is really nuked */
+#define rdmc_add_user_def rdmc_array_add_user_def
+#define rdmc_del_user_def rdmc_array_del_user_def
+#define rdmc_add_stat_def rdmc_array_add_stat_def
+#define rdmc_del_stat_def rdmc_array_del_stat_def
+#define rdmc_add_fit_def rdmc_array_add_fit_def
+#define rdmc_del_fit_def rdmc_array_del_fit_def
+#define rdmc_add_mcinfo_def rdmc_array_add_mcinfo_def
+#define rdmc_del_mcinfo_def rdmc_array_del_mcinfo_def
+#define rdmc_add_trigger_def rdmc_array_add_trigger_def
+#define rdmc_del_trigger_def rdmc_array_del_trigger_def
+
+
+/* copies all information for channel in_i from geometry *in  */
+/* to channel out_i into geometry *out  */
+void rdmc_channel_cp(array  *out,int out_i,const array *in ,int in_i); 
+
+/* in order to create objects one needs unique id's*/
+/* these functions return them */
+
+
+/* this function returns a uniqe id AND builds a uniqe tag string */
+/* on basis of tag_root. The resuklting tag is filled into tag */
+/* The function should return RDMC_NA if this operation fails, */
+/* e.g. if there are too many triggers defined */
+/* the tag usually contains the tag_root appended by a number */
+/* here the trigger number */
+int rdmc_unique_trigger_id(char *tag, const array *ar, const char *tag_root);
+int rdmc_unique_user_id(char *tag, const array *ar, const char *tag_root);
+int rdmc_unique_stat_id(char *tag, const array *ar, const char *tag_root);
+
+
+/*###########################################*/
+/**** in rdmc_hdef.c *****/
+/*###########################################*/
+
+/* add a new initilized header def */
+int  rdmc_add_array_hdef(array_hdef_t **list,
+                              int *count,
+                              array_hdef_t *new_ahdt, int ipos); 
+/* remove  header def */
+int  rdmc_del_array_hdef(array_hdef_t **list, 
+                              int *count, int ipos); 
+
+
+/* copy two structures */
+void  rdmc_cp_hdef(array_hdef_t *out, const array_hdef_t *in); 
+/* init the structures rdmc_init_array_hdef*/
+void  rdmc_init_array_hdef(array_hdef_t *def); 
+void  rdmc_clear_array_hdef(array_hdef_t *def); 
+void  rdmc_free_array_hdef(array_hdef_t *def); 
+
+/* compares two structures, retyurns 0 if they are the same or the 
+   number of differences */
+int rdmc_comp_array_hdef(const array_hdef_t *d1, 
+                         const array_hdef_t *d2);
+/* search an array of ndef array_hdef_t elements */
+/* find the number of a header definition */
+/* returns the number  0..(ndef-1) or RDMC_NA */
+int rdmc_get_hdef_tag(const array_hdef_t *hd, int ndef, const char *tag); /*according to the tag */
+int rdmc_get_hdef_id(const array_hdef_t *hd, int ndef,int id); /*according to an id */
+
+/* get a unique id for a new def object */
+int rdmc_unique_hdef_id(const array_hdef_t *p, int ndef);
+
+/* get a unique tag for a new def object. It is the tag_root itself
+ * as long it is unique, or the tag_root with a number at the end  */
+int rdmc_unique_hdef_tag(char *tag,const array_hdef_t *p, int ndef,const char *tag_root);
+
+/* returns the index of the string token in the list of hdef parameters */
+/* if the token is not found RDMC_NA is returned */
+int rdmc_token_in_hdef(const array_hdef_t *p, const char *token);
+
+
+/*###########################################*/
+/*********** in rdmc_mevt.c **************/
+/*###########################################*/
+int rdmc_revt(mcfile *fp, array *ar, mevt *ev);          /* reads an event */
+int rdmc_skipevt(mcfile *fp);                /* skips over the next event record */
+int rdmc_wevt(mcfile *fp, const mevt *ev, const array *ar);   /* writes an event */
+
+/**** init =  set to default values ****/
+/***  clear = free also memory    *****/
+void rdmc_init_mevt(mevt *ev);                    /* init the mevt structure */
+void rdmc_clear_mevt(mevt *ev);                  /* clear the mevt structure */
+void rdmc_free_mevt(mevt *ev);           /* free the internal mevt structure */
+
+/* counts number of hit channels in an event */
+/* returns number of hit channels */
+int rdmc_count_nch(const mevt *e);
+/* counts number of hit strings in an event */
+/* returns number of hit strings */
+int rdmc_count_nstr(const mevt *e);
+/* fill the string number into mhit */
+int rdmc_fill_mhit_str(mevt *ev, const array *ar);
+/* ( rdmc_fill_mhit_str rdmc_count_nstr, replace the old function ns_evt) */
+
+
+/* Routine to copy datastructures from one event (*in) to another (*out) */
+/* *out has to be allocated by the user before via: */
+/*            out = (mevt *) malloc(sizeof(mevt);  */
+/* the space required for internal substructures e.g. mtrack,mhit */
+/* is mallocated during execution of this routine */
+/* return value is 0 */
+/* previously allocated memory e.g. in tracks is NOT freed ! */
+/* in case you want to free first call: rdmc_clear_mevt(out) first */
+int rdmc_cp_mevt(mevt *out, mevt *in);
+
+/* now functions which add specific values */
+/* return value is 0 if OK */
+/* and 1 on failure */
+int rdmc_add_gen(mevt *ev, mtrack *tr, int itrack);
+int rdmc_del_gen(mevt *ev , int itrack);
+int rdmc_add_fit(mevt *ev, mtrack *ft, mevt_special_t *fr, int ifit);
+int rdmc_del_fit(mevt *ev , int ifit);
+int rdmc_add_user(mevt *ev, mevt_special_t *us, int iu);
+int rdmc_del_user(mevt *ev , int iu);
+int rdmc_add_status(mevt *ev, mevt_special_t *fr, int ifr);
+int rdmc_del_status(mevt *ev , int ifr);
+int rdmc_add_mcinfo(mevt *ev, mevt_special_t *mci, int imci);
+int rdmc_del_mcinfo(mevt *ev , int imci);
+int rdmc_add_trigger(mevt *ev, mevt_special_t *tr, int it, int id);
+int rdmc_del_trigger(mevt *ev , int it, int id);
+int rdmc_add_trig_uses(mevt *ev, mevt_uses_t *tu, int ituse);
+int rdmc_del_trig_uses(mevt *ev , int ituse);
+int rdmc_add_fit_uses(mevt *ev, mevt_uses_t *fu, int ifuse); /*ifuse is iuse number */
+int rdmc_del_fit_uses(mevt *ev , int ifuse);
+/* delete all uses for a ifit, itrig or ihit */
+int rdmc_del_ifit_uses(mevt *ev, int fitid);
+int rdmc_del_itrig_uses(mevt *ev, int trigid);
+int rdmc_del_ihit_uses(mevt *ev, int hitid);
+
+int rdmc_add_mhit(mevt *ev, mhit *h, int ihit);
+int rdmc_del_mhit(mevt *ev , int ihit);
+
+int rdmc_add_WF(mevt *ev, waveform *wf, int iwf);
+int rdmc_del_WF(mevt *ev , int iwf);
+
+
+/* now the generic function to add  initilized header def */
+int  rdmc_add_mevt_mtrack(mtrack **list, int *count, mtrack *new_mtrack,
+                         int ipos); 
+int  rdmc_add_mevt_special(mevt_special_t **list, int *count
+                          ,mevt_special_t *new_mst, int ipos); 
+int  rdmc_add_mevt_mhit(mhit **list, int *count, mhit *new_mhit, int ipos); 
+int  rdmc_add_mevt_uses(mevt_uses_t **list, int *count
+                       ,mevt_uses_t *new_mut, int ipos); 
+/* remove   */
+int  rdmc_del_mevt_mtrack(mtrack **list, int *count, int ipos); 
+int  rdmc_del_mevt_special(mevt_special_t **list, int *count, int ipos); 
+int  rdmc_del_mevt_mhit(mhit **list, int *count, int ipos); 
+int  rdmc_del_mevt_uses(mevt_uses_t **list, int *count, int ipos); 
+
+
+/* in order to create objects one needs unique id's*/
+/* these functions return them */
+int rdmc_unique_mhit_id(const mevt *ev);
+int rdmc_unique_gen_id(const mevt *ev);
+
+/* In case of corrupted hit/track ids (<0 or double counts) */
+/* this functions assign new ids to all hits (mhit.id) */
+/*     or all MC tracks (mtrack.tag)  */
+/* if inconsitiencies are detected corresponding references */
+/* e.g. uses, mhit.mt , mtrack.parent are deleted or set to RDMC_NA */
+/* returns the number of id's which wer inconsistent */
+int  rdmc_repair_mhit_id(mevt *ev); 
+int  rdmc_repair_gen_id(mevt *ev); 
+
+  /* return the index of the hit hitid */
+int rdmc_mevt_ihit(mevt *ev, int hitid);
+
+/*###########################################*/
+/*********** in rdmc_mevt_special.c **************/
+/*###########################################*/
+/* init the special structure to RDMC_NA */
+/* maxtoken is for speedup, if avaliable  */
+/* - if not, set  maxtoken < 0 and RDMC_MAXTOKEN_PER_LINE is taken*/
+void rdmc_init_mevt_special(mevt_special_t *s, int maxtoken); 
+void rdmc_clear_mevt_special(mevt_special_t *s, int maxtoken); 
+void rdmc_free_mevt_special(mevt_special_t *s); 
+/* copies the special structure in to the previusly allocated out */
+void rdmc_cp_mevt_special(mevt_special_t *out ,mevt_special_t  *in);
+/*###########################################*/
+/*********** in rdmc_mevt_uses.c **************/
+/*###########################################*/
+void rdmc_init_mevt_uses(mevt_uses_t *u);
+void rdmc_clear_mevt_uses(mevt_uses_t *u);
+void rdmc_free_mevt_uses(mevt_uses_t *u);
+/* copies nuses uses_t words from in to the previously allocated out */
+void rdmc_cp_mevt_nuses(mevt_uses_t *out, mevt_uses_t *in, int nuses);
+
+/* sorts the uses array for a) uses id and the hit_id */
+void rdmc_sort_uses(mevt_uses_t *use, int nuse);
+
+/* store all currently used hits as uses block as the given fit/trig num */
+int rdmc_create_fit_uses(mevt *e, int ifit);
+int rdmc_create_trig_uses(mevt *e, int itrig);
+
+  /* count the number of channels which are used by fit or trigger i*/
+int rdmc_count_fit_nch_uses(mevt *e, array *a, int i);
+
+
+/*###########################################*/
+/*********** in rdmc_mtrack.c **************/
+/*###########################################*/
+/* init the structure */
+void rdmc_init_mtrack(mtrack *tr);                      
+void rdmc_clear_mtrack(mtrack *tr);             /* free also */
+void rdmc_free_mtrack(mtrack *tr);             /* free only */
+
+/* copies the track *in to *out by overwriting.
+ * If in == out, nothing is done.  */
+void rdmc_cp_mtrack(mtrack *out, const mtrack *in);
+/* calcs the direction cosine from the entries tr.costh, tr.phi */
+/*  The entries  tr.px,tr.py,tr.pz are updated          */
+void rdmc_tau_tr(mtrack *tr);
+/* calcs the track angles costh, phi angle from tr.px,tr.py,tr.pz */
+/* the entries tr.costh, tr.phi are updated */
+void rdmc_tauinv_tr(mtrack *tr);
+
+
+/*###########################################*/
+/*********** in rdmc_mhit.c **************/
+/*###########################################*/
+void rdmc_init_mhit(mhit *h);                                   /* several */
+void rdmc_init_mhit_stat(mhit_stat_t *s);
+void rdmc_clear_mhit(mhit *h);             /* free also */
+void rdmc_free_mhit(mhit *h);             /* free also */
+
+void rdmc_merge_hits(mhit *h1, mhit *h2, int ch);
+/* merges two hits  *hit_1 *hit_2 of the same channel */
+/*     filling them into *hit_1 */
+/*  - amplitudes are added */
+/*  - the earliest time of hit is taken*/
+/*  - mt is used from the earliest hit */
+/*  - ma is taken from the hit with the largest amplitude */
+/*  - ch and str  remain unchanged */
+/*  - since rdmc-1.9 mhit->tot is added substracting the overlap*/
+/*               tot = tot_1 + tot_2 - (overlap) */
+/* the  amplitude of the merged hit is added only if ch=-1
+ * else the amplitude of the channel ch is used.
+ * If there is no such channel, a zero amplitude is assumed
+ */
+
+void rdmc_cp_mhit(mhit *out, mhit *in);
+/* copies the hit *in to *out by overwriting.
+ * If in == out, nothing is done.
+ */
+
+
+
+/*###########################################*/
+/*********** in rdmc_WF.c **************/
+/*###########################################*/
+void rdmc_init_WF(waveform *wf);                 /* several */
+void rdmc_clear_WF(waveform *wf);             /* free also */
+void rdmc_free_WF(waveform *wf);               /* free also */
+
+
+void rdmc_cp_WF(waveform *out, waveform *in);
+/* copies the waveform *in to *out by overwriting.
+ * If in == out, nothing is done.
+ */
+
+
+
+/*###########################################*/
+/**** in rdmc_jk *******/
+/*###########################################*/
+/* this implements functions that provide compatibility to the old 
+   jk structure of rdmc-1.x */
+/* the indices of the special structure values in "rdmc-jk" */
+#define JK_N_TOKEN  8                 /* number of FRESULT tokens */
+#define JK_FITID 0                    /* an id of the fit algorithm */
+#define JK_RCHI2 1                    /* chi2/NDF or Likelihood/nch */
+#define JK_PROB 2                     /* some reco result parameter */
+#define JK_SIGTH 3                    /* some reco result parameter */
+#define JK_COVMIN 4                   /* some reco result parameter */
+#define JK_COVMAX 5                   /* some reco result parameter */
+#define JK_CUTFLAG 6                  /* some reco result parameter */
+#define JK_CHI2 7                             /* chi2 or likelihood */
+
+/* initilizes a header definition as  "rdmc-jk"  */
+void rdmc_jk_to_fitdef(array_hdef_t *jk_def, int id);
+
+/* init values of fitresult as expected for "rdmc-jk" (similar to init_jk) */
+void rdmc_init_fit_jk(mevt_special_t *result,int id);
+
+/* checks if fresult ifit is a rdmc-jk fresult returns 1 if yes else 0*/
+int rdmc_is_fresult_jk(const array *ar, const mevt *ev, int ifit);
+
+/* checks if special fresult is defined as rdmc-jk  returns 1 if yes 
+   else 0*/
+int rdmc_is_this_jk(const array_hdef_t *jk_def, const mevt_special_t *result);
+
+/* returns 1 if fitdef idef (0..ar->n_fit-1) is of jk type */
+int rdmc_is_fitdef_jk(const array *ar,int idef);
+
+#if 1
+extern const array_hdef_t rdmc_jk_fit_def;
+#endif
+
+/*###########################################*/
+/********* in rdmc_time.c **********/
+/*###########################################*/
+
+time_t rdmc_o_dateconv(int date);  /* converts a YYMMDD date into unix time */
+int rdmc_o_rdateconv(time_t time); /* converts unix time into YYMMDD format */
+
+int rdmc_gps_to_mjd(int gpsyear, int gpsday);    /* convert GPS date to mjd */
+void rdmc_mjd_to_gps(int mjd, int *gpsyear, int *gpsday);     /* mjd to GPS */
+void rdmc_tjd_to_mjd(int tjd, double sec, int *mjd, int *secs, int *ns);
+       /* convert truncated julian days to mjd */
+void rdmc_mjd_to_tjd(int mjd, int secs, int ns, int *tjd, double *sec); 
+       /* convert mjd to tjd */
+void rdmc_jd_to_mjd(double jd, int *mjd, int *secs, int *ns);   
+        /* convert jd to mjd */
+void rdmc_mjd_to_jd(int mjd, int secs, int ns, double *jd);    
+        /* convert mjd to jd */
+time_t rdmc_mjd_to_unixtime(int mjd, int secs); /* convert mjd in unix secs */
+int rdmc_unixtime_to_mjd(time_t unix_time);     /* convert unix secs in mjd */
+int rdmc_unixtime_to_mjdsecs(time_t unix_time);    /* unix secs in mjd secs */
+void rdmc_jd_to_gmst(double jd, double *gmst); 
+       /* Julian Days to Greenwich mean sidereal time */
+void rdmc_gmst_to_jd(double gmst, int intjd, double *jd);     
+       /* convert gmst to jd */
+
+/*###########################################*/
+/********* in rdmc_local.c **********/
+/*###########################################*/
+
+char *rdmc_which_format(mcfile *fp);  /* returns string with the format name*/
+
+
+/*###########################################*/
+/********* in amanda.c **********/
+/*###########################################*/
+
+
+/*###########################################*/
+/********* in f2k_utl.c **********/
+/*###########################################*/
+
+
+int rdmc_is_f2000_supported(int major, int minor);   /* returns 1 if f2000 */
+                                             /*format version is supportet */
+/* return the rdmc value for the OM/PMT string and vive versa */
+int rdmc_amanda_iomid(const char *str, int ar_id);
+int rdmc_amanda_ipmtid(const char *str);
+const char *rdmc_amanda_spmtid(int type);
+const char *rdmc_amanda_somid(int id);
+/* convert rdmc particle ids to f2000 names and vice versa */
+int rdmc_amanda_ipartid(const char *name);
+const char *rdmc_amanda_spartid(int id);
+/* convert rdmc detector ids to f2000 names and vice versa */
+const  char * rdmc_amanda_sdet(int geo_id); /* returns a pointer to the name */
+int rdmc_amanda_idet(const char *detnam);     /* return the id */
+/* WARNING the returned pointers are static local strings, which values may change so do not work on these but imediately copy the contnt to yozur private variable */
+
+
+/*###########################################*/
+/* routines in rdmc_phys.c           */
+/*###########################################*/
+
+/*****************************************************************************/
+/* global const, variables                                                   */
+/*****************************************************************************/
+
+extern const double rdmc_c_vacuum; /* m/nsec; light speed in vacuum */
+extern const double rdmc_rez_c_vacuum;        /* 1/c  [ ns/m ] */
+
+#ifndef RDMC_OLD_REFIDX
+#define RDMC_OLD_REFIDX 0 /* use the old value of the refraction index */
+#endif
+
+#if RDMC_OLD_REFIDX
+extern const double c_water;                 /* m/nsec; light speed in water */
+extern const double rez_c_water;                        /* 1/c_water [ns/m ] */
+extern const double n_water;                    /* refraction index of water */
+extern const double cer;                                   /* cerenkov angle */
+extern const double tg_cer;                     /* tangens of cerenkov angle */
+extern const double sn_cer;                                  /* sin cerencov */
+extern const double rez_sn_cer;                            /* 1/sin cerencov */
+extern const double cs_cer;                                  /* cos cerencov */
+#else
+extern const double rdmc_n_water; /* refraction index of water */
+extern const double rdmc_n_ice_p;/* phase refraction index of water */
+extern const double rdmc_n_ice_g;/* group refraction index of water */
+extern const double rdmc_c_water; /* m/nsec;  speed in water */
+extern const double rdmc_rez_c_water;/* nsec/m;  speed in water */
+extern const double rdmc_c_ice_p; /* m/nsec; speed in water */
+extern const double rdmc_rez_c_ice_p;/* nsec/m;  speed in water */
+extern const double rdmc_c_ice_g; /* m/nsec;  speed in water */
+extern const double rdmc_rez_c_ice_g; /* nsec/m;  speed in water */
+extern const double rdmc_cs_cer_wat;       /* cos cerencov */
+extern const double rdmc_cs_cer_ice_p;     /* cos cerencov */
+extern const double rdmc_cs_cer_ice_g;     /* cos cerencov */
+extern const double rdmc_cer_wat;       /* cerenkov angle in rad */
+extern const double rdmc_cer_ice_p;   /* cerenkov angle in rad */
+extern const double rdmc_cer_ice_g;   /* cerenkov angle in rad */
+extern const double rdmc_sn_cer_wat;   /* sin cerencov */
+extern const double rdmc_sn_cer_ice_p; /* sin cerencov */
+extern const double rdmc_sn_cer_ice_g; /* sin cerencov */
+extern const double rdmc_rez_sn_cer_wat;    /* 1/sin cerencov */
+extern const double rdmc_rez_sn_cer_ice_p; /* 1/sin cerencov */
+extern const double rdmc_rez_sn_cer_ice_g; /* 1/sin cerencov */
+extern const double rdmc_tg_cer_wat; /*tan  cer */
+extern const double rdmc_tg_cer_ice_p; /*tan cer */
+extern const double rdmc_tg_cer_ice_g; /*tan cer */
+extern const double rdmc_tg_cer_tkoeff; /* koefficient in rdmc_art()  */
+#endif
+
+int rdmc_track_closest(double *dist, double poca_xyz[3], 
+                   const mtrack *it, const double x, 
+                   const double y, const double z);
+/* calculates the distance of closest approach to point of coordinates x,y,z*/
+/* it returns the values: perpendicular distance *dist */
+/* vector poca_xyz[3] with coordinates of the track point of closest aproach */
+/* both dist or xyz may be NULL pointers if you do not want to calculate this*/
+
+
+int rdmc_track_delta(float *delta, float *dist,
+                    const mtrack *tr1, const mtrack *tr2);
+/* calculates the angular difference (solid angle) between two tracks */
+/* and the closest distance between them */
+int rdmc_deltaang(double theta1, double phi1, double theta2, 
+                       double phi2, double *delta);
+/* calculate the angular difference between two directions given by */
+/* four angles */
+
+
+
+/* calculate the cherenkov arrival times */
+double rdmc_art_xyz(const mtrack *tr, double x, double y, double z); 
+                                          /* Cerenkov light arrival to point */
+
+double rdmc_art(const array *ar, const mtrack *tr, int i); 
+                                       /* Cerenkov light arrival to i-th pmt */
+
+double rdmc_pnt_art(const array *ar, const mtrack *tr, int i);
+                                         /* arrival time from a point source */
+
+double rdmc_om_dist(const array *a, int ich1, int ich2); /* distance between */
+                                                        /* 2 channels */
+
+double rdmc_dist(double x1, double y1, double z1,        /* distance between */
+                double x2, double y2, double z2);               /* 2 points */
+
+/* rdmc_angtr() calculates the cosinus of the direction angles between two  */
+/*   tracks: returns between 1. (parrallel) and -1. (antiparallel)          */
+double rdmc_angtr(const mtrack *t1, const mtrack *t2);
+
+double rdmc_tdist_xyz(const mtrack *it, double x, double y, double z);
+                           /* calcs the min distance from a track to a point */
+double rdmc_tdist(const array *ar, const mtrack *it, int iom);
+                         /* calcs the min distance between a track and an om */
+double rdmc_tdist_orig(const mtrack *it); 
+            /* calcs the min distance between a track and the origin (0,0,0) */
+
+double rdmc_vdist(const array *ar, const mtrack *it, int iom);
+/* calcs the distance between a the vertex of track and a pmt       */
+
+void rdmc_tang(const array *ar, const mtrack *it, int iom, 
+           double *dist, double *csang);
+
+
+void rdmc_vang(const array *ar, const mtrack *it, int iom, 
+           double *dist, double *csaxis, double *csang);
+
+/*calculates the perpendicular distance, direction angle and  cos(angle) */
+/* of incident light if dist, csaxis or csang are NULL, */
+/* they are not calculated */
+
+
+/*###########################################*/
+/* routines in rdmc_utl.c           */
+/*###########################################*/
+
+void rdmc_add_timeoffset(mevt *e, float offset);
+/* adds a time offset to all time related values of an event */
+/* this are presently ONLY the hit times, and the fit/gen track times */
+
+/* sort hits in a event by a call to quicksort either by time */
+/*  or by channel number */
+int rdmc_sort_hits(mevt *ev, const array *ar, enum RDMC_SORT_T method);
+
+/* remove fit no ifit (counting is: 0..nfit-1) from event */
+/* including all associated information, like fit_uses */
+void rdmc_remove_fit(mevt *e, int ifit);
+
+/* remove_groups() removes all hits which are not from the leading muon */
+/* (invert=0) or which are from the leading muon (invert=1) */
+/* returns the number of hits after the procedure */
+/* Noise is treated according to the last flag */
+/* ev->nch and ev->nstr is NOT updated !!! */
+int rdmc_remove_groups(mevt *e, int invert,int keep_noise);
+
+/* remove a hit from the event */
+/* including all associated information, like fit_uses */
+/* ev->nch and ev->nstr is NOT updated !!! */
+void rdmc_remove_hit(mevt *e, int ihit);
+
+/* Return mtrack->tag of track-like parent of a track */
+int rdmc_tracklike_parent(const mevt *e,const mtrack *t);
+
+/* returns 1 if this is a secondary shower else 0 */
+int rdmc_is_secondary(mtrack *t);
+int rdmc_is_neutrino(mtrack *t);
+int rdmc_is_cr_primary(mtrack *t);
+
+/* returns 1 if this mtrack is a point-like or track-like light source */
+int rdmc_is_point_like(const mtrack *t);
+int rdmc_is_track_like(const mtrack *t);
+
+/****************************************************************************/
+/* checks if this hit is a  ifold  [scip] coincident hit                   */
+/* returns 1 if yes, 0if no                                                 */
+/****************************************************************************/
+int rdmc_is_coinc(mevt *e, const array *ar, int ihit, 
+                        int fold, float twin);
+int rdmc_is_scoinc(mevt *e, const array *ar, int ihit, 
+                        int fold, float twin);
+
+/* calculates the number of neighbouring hits */
+/* which are coincident in the time window twin */
+/* and are within the radius */
+/* returns -1 on error */
+int rdmc_neighbours(array *a, mevt *e, int ihit, double radius, double twin);
+
+
+int rdmc_count_geo(const array *a);
+/* counts number of strings in an geometry-array *a and returns that number */
+
+void rdmc_make_str(array *a);   
+/* cleans up the geometry data structure *a */
+/* the number of strings (a->nstr) is recalculated */
+/* and the string number for each chanel (a->str[i]) are  recalculated */
+
+void rdmc_make_clust(array *a); 
+/* calculates the iclust number for each channel in the data structure *a */
+/* the old value a->clust[i] is deleted  (Baikal specific) */
+
+int rdmc_give_clust(const array *a,int ich);
+/* this function calculates the value iclust for channel ich in array *a */
+/* the function returns the result iclust or -1 on error */
+/*  (Baikal specific) */
+
+double rdmc_count_pe(const mevt *e);
+/* calculate total pe in this event */
+
+int rdmc_omhit(float *pesum, int iom, const mevt *event);
+/* calculates the sum of PE in OM iom ([0..nom-1]) */
+/* return 0 if the om was not hit else 1 */
+
+double rdmc_count_ompe(const mevt *e,const array *a
+                      ,float pe_oms[],int hit_oms[]);
+/* calculates for each om if it was hit, */
+/* and how many PE (ADCs summed over all hits) this are */
+/* the  arrays pe_oms[] and hit_oms[] are initlized to 0 */
+/* but have to be provided by the user (size: ar->nch) */
+/* it fills 1 into hit_om[i] if the channel i was hit */
+/*     and fills total pe of all hits in this OM into pe_oms[i] */
+/* returns the total number of pe of all OM                     */
+/* the function can be called with pe_oms or hit_oms set to NULL */
+/* then the corresponding values are not calculated (efficiency) */
+
+int rdmc_centre(const mevt *ev, const array *geom, double rc[3]
+               , double amp_pwr);
+/* calculate the vector rc to the centre of gravity of the event */
+/* amp_pwr is the power by which the amplitude is to be weighted */
+
+
+/*###########################################*/
+/* routines in rdmc_genutl.c           */
+/*###########################################*/
+  /* returns the index of the track in mevt.gen or RDMC_NA
+     if not found */
+
+int rdmc_which_gen(mevt *e, enum RDMC_GENINFO_T selection);
+
+  /* get the leading muon from the tracks */
+  /*  OLD routine, kept for backward compatibility */
+  /* eqivalent to rdmc_which_gen(e, MOST_HITS_MUON); */
+int rdmc_get_leading_muon(mevt *e);  /* OBSOLETE */
+
+/* ************************************************************************ */
+/* sort_generated_tracks() sorts all generated tracks with respect to the   */
+/*  number of hits caused by the track,  */
+/* and removes tracks without hits   if  keep_tracks==0 && keep_all==0 */
+/* and keeps all tracks    if   keep_all==1 */
+/* and removes secondaries (no muon!) without hits   if  keep_tracks=1 */
+/****************************************************************************/
+void rdmc_sort_generated_tracks(mevt *e, int keep_tracks, int keep_all);
+
+
+
+/*###########################################*/
+/* routines in rdmc_sky.c           */
+/*###########################################*/
+void rdmc_spdetec2radec(int mjd, int sec, int nsec, double th, double ph,
+                     double *ra, double *dec); 
+void rdmc_radec2spdetec(int mjd, int sec, int nsec, double ra, double dec,
+                       double *theta, double *phi);
+void rdmc_old_spdetec2radec(int mjd, int sec, int nsec, double th, double ph,
+                     double *ra2, double *dec2); 
+  /* transform south pole detector to equatorial coordinates */
+void rdmc_radec2llbb(double ra, double dec, double *ll, double *bb);
+  /* transform equatorial to galactic coordinates */
+void rdmc_llbb2radec(double ll, double bb, double *ra, double *dec);
+  /* transform galactic to equatorial coordinates */
+void rdmc_llbb2sllsbb(double ll, double bb, double *sll, double *sbb);
+  /* transform galactic to supergalactic coordinates */
+void rdmc_sllsbb2llbb(double sll, double sbb, double *ll, double *bb);
+  /* transform supergalactic to galactic coordinates */
+void rdmc_radec2ecliptic(int mjd, int sec, int nsec, double ra, double dec, 
+                        double *lamda, double *beta);
+  /* transform equatorial to ecliptic coordinates */
+void rdmc_ecliptic2radec(int mjd, int sec, int nsec, double lamda, 
+                        double beta, double *ra, double *dec);
+  /* transform ecliptic to equatorial coordinates */
+void rdmc_lunarradec(int mjd, int sec, int nsec, double *ra, double *dec);
+  /* calculate the position of the moon in equatorial coordinates */
+void rdmc_solarradec(int mjd, int sec, int nsec, double *ra, double *dec);
+  /* calculate the position of the sun in equatorial coordinates */
+void rdmc_solar_anomaly(int mjd, int sec, int nsec, 
+                       double *lamda_s, double *M_s);
+  /* calculate coordinates needed for rdmc_solarradec and rdmc_lunarradec */
+void rdmc_get_obliquity(int mjd, int sec, int nsec, double *obl);
+  /* calculate the obliquity needed for ecliptic coordinates */
+
+
+/*###########################################*/
+/* routines in astrocoord.c OBSOLETE          */
+/*###########################################*/
+void rdmc_coord(float gpssec, int gpsday, int gpsyear, float th, float ph,
+          float *ra, float *dec, float *ll, float *bb);
+  /* OBSOLETE use functuions in rdmc_sky.c */
+
+
+
+/*###########################################*/
+/* routines in rdmc_clean_hits.c           */
+/*###########################################*/
+
+typedef struct {
+  int modify_mhit;    /* flag to indicate modification of mhit  during fit*/
+} rdmc_clean_hit_t;
+
+/*****************   PS hit  selection structure   ************************/
+//                              +--------------------------------+
+//                              | new structure for hit cleaning |
+//                              +--------------------------------+
+typedef struct {
+  char cut;
+  int ia1,ia2;
+  float fa1,fa2,fa3;
+} hit_sel_options;
+typedef struct {
+  int id;
+  int modify_mhit;    /* flag to indicate modification of mhit  during fit*/
+  hit_sel_options* opt;
+} rdmc_clean_hit_ps;
+/*****************  * * * * * * * * * * * * * * *  ************************/
+
+extern  rdmc_clean_hit_ps rdmc_clean_hit;
+
+//                              +--------------------------------+
+//                              | init. selection options        |
+//                              +--------------------------------+
+void hit_sel_options_init(rdmc_clean_hit_ps** phit_options);
+//                              +--------------------------------+
+//                              |  init. new  selection param.   |
+//                              +--------------------------------+
+void ps_new_sel_opt(rdmc_clean_hit_ps* phit_options);
+//                              +--------------------------------+
+//                              |  clear selection options       |
+//                              +--------------------------------+
+void ps_clear_sel_opt(rdmc_clean_hit_ps* phit_options);
+//                              +--------------------------------+
+//                              |  parse  selection options      |
+//                              +--------------------------------+
+int ps_parse_sel_opt(const char *optarg,const char *progname
+                     ,rdmc_clean_hit_ps* phit_options);
+//                              +--------------------------------+
+//                              |  print selection options       |
+//                              +--------------------------------+
+void ps_usage_cleaning();
+void ps_print_sel_opt(const char *progname
+                      ,rdmc_clean_hit_ps* phit_options);
+//                              +--------------------------------+
+//                              | do hit cleaning                |
+//                              +--------------------------------+
+int ps_exec_cleaning(mevt *e, array *a, rdmc_clean_hit_ps* phit_options);
+
+
+void rdmc_usage_cleaning(void); /* print all cleaning options == help */
+int rdmc_parse_cleaning(const char *optarg,const char *progname);  
+/* parse the cleaning command line */
+void rdmc_print_cleaning(const char *progname);    /* print the cleaning options */
+
+/* make a copy of the hit data structure return 1 on error */
+int rdmc_clean_backup_hits(mevt *e);
+/* restore the backuped copy  return 1 on error */
+int rdmc_clean_restore_hits(mevt *e);
+
+/* function does recalculate mevt.nch and mevt.nstr */
+int rdmc_exec_cleaning(mevt *e, array *a);    /* delete hits to be cleaned */
+
+/* clear the internal list -> experts use only */
+void rdmc_clear_cleaning_list(void); /* reset/clean cleaning list */
+
+/* rountines do not recalculate mevt.nch and mevt.nstr */
+int rdmc_rm_h(array *a, mevt *e, int hit_nr,int nhits);   /* remove one hit */
+                                                    /* hit_nr: 0..(nhit-1) */
+int rdmc_rm_rnd_h(array *a, mevt *e);             /* remove one random hit */
+                                                    /* returns ihit*/
+int rdmc_rm_rnd_nh(array *a, mevt *e, int n);        /* remove n random hits */
+                                                    /* returns number of hits*/
+int rdmc_rm_earliest_h(array *a, mevt *e,int num); 
+                                           /* remove num earliest hit*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_latest_h(array *a, mevt *e,int num);
+                                           /* remove num latest hit */
+                                           /* return number of removed hits */ 
+int rdmc_rm_interval_h(array *a, mevt *e,float before, float after);
+                                           /* remove outside time window */
+                                           /* return number of removed hits */
+int rdmc_rm_amp_h(array *a, mevt *e,float amp_low, float amp_high, 
+                 int low_channel, int high_channel);
+                                     /*remove hits amp_low > amp > amp_high */
+                                           /* return number of removed hits */
+int rdmc_rm_tot_h(array *a, mevt *e,float tot_low, float tot_high,
+                 int low_channel, int high_channel);
+                                     /*remove hits tot_low > tot > tot_high */
+                                           /* return number of removed hits */
+int rdmc_rm_nocoinc_h(array *a, mevt *e
+                     , int coinc, float twin); 
+                                         /*remove  coinc-fold  hits*/
+                                        /* the time window twin is aplied */
+                                        /* return number of removed hits */ 
+int rdmc_rm_snocoinc_h(array *a, mevt *e
+                      , int coinc, float twin); 
+                                         /*remove SKIP coinc-fold  hits*/
+                                        /* the time window twin is aplied */
+                                        /* return number of removed hits */ 
+int rdmc_rm_isolate_h(array *a, mevt *e,float window);
+                                             /*time separated hits by window*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_coinc_h(array *a, mevt *e,float window);
+                                             /*time coincident hits in window*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_xtalk_h(array *a, mevt *e, float window, float adc_min, 
+                   float ratio);
+  /* remove LE-coincident cross-talk */
+int rdmc_rm_xtalk_map_h(array *a, mevt *e, float adc_min, float ratio);
+  /* remove x-talk using Klug & Hanson channel maps, Klug's time windows */
+                                           /* return number of removed hits */ 
+int rdmc_rm_local_h(array *a, mevt *e, double radius, double twin, int nhits);
+                          /* local space and time isolated hits are removed */
+                              /* at least nhits within radius and time twin */
+int rdmc_rm_additional_h(array *a, mevt *e,int from);
+                                           /* remove additional hits in 
+                                            each channel*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_channel_h(array *a, mevt *e,int ich);
+                            /* OBSOLETE remove all hits in channel ich*/
+int rdmc_rm_channels_h(array *a, mevt *e,int ich1, int ich2);
+                          /*remove all hits from channel ich1 to ich2*/
+int rdmc_rm_string_h(array *a, mevt *e,int istr);
+                                           /*remove all hits in string istr*/
+int rdmc_rm_uses_h(array *a, mevt *e,int itrig);
+                                           /* remove hits not used by trigger 
+                                            itrig*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_fuses_h(array *a, mevt *e,int ifit);
+                                           /* remove hits not used by fit 
+                                            ifit*/
+                                           /* return number of removed hits */ 
+int rdmc_rm_imhoff_h (array *a, mevt *e, int n);
+                                          /* remove the hits with highest/lowest */
+                                          /* (t-t_bar)*(z-z_bar) */
+int rdmc_rm_imhoff_s_h (array *a, mevt *e, double r, int s);
+                                           /* remove the hits with a */
+                                           /* (t-t_bar)*(z-z_bar)  */
+                                           /*  above/above and  below/below*/
+                                           /* r*sigma of the (t)(z) */
+                                           /* if s>/=/<0 */
+int rdmc_rm_early_amp_h(array *a, mevt *e,int num, float amp_high);
+                                     /* within first num hits, hits with */
+                                   /* amplitude larger than amp are removed */ 
+int rdmc_rm_amp_early_h(array *a, mevt *e,int num, float amp_high);
+                                     /* within first num hits, hits with */
+                                   /* amplitude larger than amp are removed */ 
+int rdmc_rm_dt_rho_h(array *a, mevt *e, int ifit, float rho, float tmin, float tmax);                              /* removes  (truncates) hits with */
+              /*distance rho and outside time-window tmin,tmax from fit */
+
+int rdmc_rm_inrho_h(array *a, mevt *e, int ifit, float rho);                              /* removes  (truncates) hits with radius smaller than rho from fit */
+int  rdmc_rm_tunnel_h(array *a, mevt *e, int mode);
+int rdmc_rm_split_h (array *a, mevt *e, int splitorder, int splitmode);
+
+/*###########################################*/
+/* routines in pandel_track.c and pandel_point.c      */
+/*###########################################*/
+/* naming convention: */
+/*   _pt_... : track 
+     _pp_...:  point
+
+     _td_ : time delay
+     _ph_ : phit _pnh_: nohit 
+
+     lg : logarithm
+
+     norm : normalisation = integral  to infinity of unormalize function.
+     int : cumulative integral to time t
+     diff : d/dt differential
+
+     mpe : multi pe
+     psa : poisson saturated
+
+     patched: a patched pandel approach
+*/
+
+/* init the physics constants */
+/*if one does not which to overwrite a certain value 
+ then call with a large negative value (<= RDMC_SPECIAL_NA)*/
+typedef struct {
+  double td_tau;     /* tau for tracks */
+  double td_lam;     /* lambda for tracks */
+  double td_att;     /* Absorption lenght */
+  double ps_tau;     /* tau for tracks */
+  double ps_lam;     /* lambda for tracks */
+  double td_sigma;   /* pmt jitter -> patched functions */
+  double td_dist_p1; /* scale for the distance */
+  double td_dist_p0_cs0; /* const for distance ped (P0) */
+  double td_dist_p0_cs1; /* const for distance ped (P1*cs_ori) */
+  double td_dist_p0_cs2; /* const for distance ped (P2*cs_ori^2) */
+  double td_ph_eps_pe0;
+  double td_ph_eps_pe1;
+  double td_ph_eps_ori_n0;
+  double td_ph_eps_ori_pow;
+  double td_ph_dist_a;
+  double td_ph_dist_b;
+  double td_ph_dist_l;
+  double td_ph_dist_e0;
+} rdmc_pandel_par_t;
+
+
+extern const  rdmc_pandel_par_t 
+  rdmc_pandel_par_h0, /* No irregulaarities in the hole */
+  rdmc_pandel_par_h1, /* hole irregularities scat=100cm */
+  rdmc_pandel_par_h2, /* hole irregularities scat=50cm */
+  rdmc_pandel_par_h3, /* hole irregularities scat=30cm */
+  rdmc_pandel_par_h4; /* hole irregularities scat=10cm */
+
+
+void rdmc_td_init(rdmc_pandel_par_t *pandel_par);
+
+/* now the functions */
+double rdmc_pt_td(double delay, double perp_dist, double cs_ori);
+double rdmc_pt_lgtd(double delay, double perp_dist, double cs_ori);
+
+double rdmc_pt_td_norm(double perp_dist, double cs_ori);
+double rdmc_pt_lgtd_norm(double perp_dist, double cs_ori);
+
+double rdmc_pt_td_int(double delay, double perp_dist, double cs_ori);
+double rdmc_pt_lgtd_int(double delay, double perp_dist, double cs_ori);
+double rdmc_pt_td_diff(double delay, double perp_dist, double cs_ori);
+
+
+double rdmc_pt_td_mpe(double delay,double perp_dist,double cs_ori,double pe);
+double rdmc_pt_lgtd_mpe(double delay,double perp_dist,double cs_ori,double pe);
+
+double rdmc_pt_td_mpe_int(double delay,double perp_dist,double cs_ori,double pe);
+double rdmc_pt_lgtd_mpe_int(double delay,double perp_dist,double cs_ori,double pe);
+double rdmc_pt_td_mpe_diff(double delay,double perp_dist,double cs_ori,double pe);
+
+double rdmc_pt_td_psa(double delay, double perp_dist, double cs_ori, double mean_pe);
+double rdmc_pt_lgtd_psa(double delay, double perp_dist, double cs_ori, double mean_pe);
+
+double rdmc_pt_td_psa_int(double delay, double perp_dist, double cs_ori, double mean_pe);
+double rdmc_pt_lgtd_psa_int(double delay, double perp_dist, double cs_ori, double mean_pe);
+double rdmc_pt_td_psa_diff(double delay, double perp_dist, double cs_ori, double mean_pe);
+
+
+double rdmc_pt_td_patched(double delay, double perp_dist, double cs_ori);
+double rdmc_pt_lgtd_patched(double delay, double perp_dist, double cs_ori);
+
+double rdmc_pt_td_mpe_patched(double delay, double perp_dist, double cs_ori, double pe);
+double rdmc_pt_lgtd_mpe_patched(double delay, double perp_dist, double cs_ori, double pe);
+
+double rdmc_pt_td_psa_patched(double delay, double perp_dist, double cs_ori, double mean_pe);
+double rdmc_pt_lgtd_psa_patched(double delay, double perp_dist, double cs_ori, double mean_pe);
+
+double rdmc_pt_ph(double perp_dist, double cs_ori, double energy, double sensit);
+double rdmc_pt_pnh(double perp_dist, double cs_ori, double energy, double sensit);
+double rdmc_pt_ph_dt(double perp_dist, double cs_ori, double energy, double sensit, double tmin, double tmax);
+double rdmc_pt_pnh_dt(double perp_dist, double cs_ori, double energy, double sensit, double tmin, double tmax);
+
+double rdmc_pp_td(double delay, double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_lgtd(double delay, double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_td_norm(double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_lgtd_norm(double perp_dist, double cs_ori, double cs_axis);
+
+
+double rdmc_pp_td_int(double delay, double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_lgtd_int(double delay, double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_td_diff(double delay, double perp_dist, double cs_ori, double cs_axis);
+
+
+double rdmc_pp_td_mpe(double delay,double perp_dist,double cs_ori, double cs_axis,double pe);
+double rdmc_pp_lgtd_mpe(double delay,double perp_dist,double cs_ori, double cs_axis,double pe);
+
+double rdmc_pp_td_mpe_int(double delay,double perp_dist,double cs_ori, double cs_axis,double pe);
+double rdmc_pp_lgtd_mpe_int(double delay,double perp_dist,double cs_ori, double cs_axis,double pe);
+double rdmc_pp_td_mpe_diff(double delay,double perp_dist,double cs_ori, double cs_axis,double pe);
+
+double rdmc_pp_td_psa(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+double rdmc_pp_lgtd_psa(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+
+double rdmc_pp_td_psa_int(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+double rdmc_pp_lgtd_psa_int(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+double rdmc_pp_td_psa_diff(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+
+double rdmc_pp_td_psd_patched(double delay, double dist, double cs_ori, double cs_axis, double mean_pe);
+double rdmc_pp_td_patched_int(double delay, double dist, double cs_ori, double cs_axis);
+
+
+double rdmc_pp_td_patched(double delay, double perp_dist, double cs_ori, double cs_axis);
+double rdmc_pp_lgtd_patched(double delay, double perp_dist, double cs_ori, double cs_axis);
+
+double rdmc_pp_td_mpe_patched(double delay, double perp_dist, double cs_ori, double cs_axis, double pe);
+double rdmc_pp_lgtd_mpe_patched(double delay, double perp_dist, double cs_ori, double cs_axis, double pe);
+
+double rdmc_pp_td_psa_patched(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+double rdmc_pp_lgtd_psa_patched(double delay, double perp_dist, double cs_ori, double cs_axis, double mean_pe);
+
+#if 0 /* Not all functions for point sources are implemented yet */ 
+double rdmc_pp_ph(double perp_dist, double cs_axis, double energy, double sensit);
+double rdmc_pp_pnh(double perp_dist, double cs_axis, double energy, double sensit);
+#endif
+
+/*###########################################*/
+/* routines in rdmc_ndirect.c           */
+/*###########################################*/
+/****************************************************************************/
+/* rdmc_get_direct_hits calcultes the number of direct early and delayed hits*/
+/*   The number of arguments is variable                                    */
+/*   A format string is passed  */
+/*      for each additional argument it has the form: t-:t+;f   */
+/*       t- and t+ define the time window                        */
+/*       f is a format id:                                        */
+/*         'c'   asks for a number of channels              */
+/*         's'   asks for a number of strings              */
+/*         'd'   asks for the smallest perpendicular distance between the */
+/*               track and a hit */
+/*         'D'   asks for the largest perp distance between track and a hit */
+/*         'R'   asks for the average perp distance between track and a hit */
+/*         'L'   asks for the length of hits projected on the track */
+/*                = Zdist(baikal)  */
+/*         'M'   asks for the projected length on the track of all hits */
+/*                but one: leaving out the most outlying direct hit  */
+/*         'O'   Get the largest polar angle in the projection of hits */
+/*               onto the plane perp to the track direction */
+/*         'x','y','z' = centre of gravity of direct hits */
+/*   example : */
+/*     get_direct_hits("-10000.:-5.;c -5.:35.;c -5.:20.;s 75.:10000.;c" */
+/*         ,&nearly,&ndir,&nsdir,&nlate);*/
+/* the function returns gdir */
+/****************************************************************************/
+double rdmc_get_direct_hits(const array *a, const mtrack *tr, mevt *e
+                           , const char *fmt, ...);
+
+/*###########################################*/
+/* routines in rdmc_math.c           */
+/*###########################################*/
+double rdmc_lgamma(double x);  /* logarithm of the gamma-function */
+double rdmc_gamac(double a, double x); /* incomplete gamma function */
+long rdmc_nint(double a);                      /* double to nearest integer */
+void rdmc_vecprod(const double a[3], const double b[3], double c[3]);
+double rdmc_scalprod(const double a[3], const double b[3]);
+/*###########################################*/
+/* routines in random.c           */
+/*###########################################*/
+double rdmc_rand(void);             /* random number s from numerical recipes*/
+double rdmc_poidev(double xm);        /* poisson value with mean xm */
+double rdmc_gasdev(void);                /* gaussian random number */
+
+
+/*###########################################*/
+/* routines in  messages.c                   */
+/*###########################################*/
+
+void rdmc_msgprintf(const char *fmt, ...);
+/* msgprintf() prints out a message                                         */
+void rdmc_errorprintf(const char *fmt, ...);
+/* errorprintf() prints out an error message                                */
+void rdmc_warnprintf(const char *fmt, ...);
+/* warnprintf() prints out a warning message                                */
+
+/*###########################################*/
+/* routines in  rdmc_error.c                   */
+/*###########################################*/
+
+void rdmc_err_print(mcfile *fp, enum RDMC_ERROR_T ierr);
+/* gives more verbose info after an rdmc error occured */
+
+/*###########################################*/
+/* routines in  rdmc_poem.c                   */
+/*###########################################*/
+
+const char *rdmc_poem(void);
+
+
+/*###########################################*/
+/* routines for Fortran in f_rdmc.c          */
+/*###########################################*/
+
+
+void frdmc_mcopen_(char *name, int* mode, int *format, int *res);
+void frdmc_mcclose_(int *mode, int *res);
+void frdmc_rarr_   (int *res);
+void frdmc_revt_   (int *res);
+void frdmc_skipevt_(int *res);
+void frdmc_warr_   (int *res);
+void frdmc_wevt_   (int *res);
+
+/* filling adding and ddeletion functions */
+void frdmc_fill_gen_(int *itrack, int *result); 
+void frdmc_fill_rec_(int *itrack, int *result);
+void frdmc_fill_user_(int *iuser, int *result);
+void frdmc_fill_usdef_(int *iuser, int *result);
+void frdmc_fill_wf_(int *iwf, int *result);
+void frdmc_new_gen_(int *itrack, int *result);
+void frdmc_new_rec_(int *itrack, int *idef, int *result);
+void frdmc_new_user_(int *iuser, int *idef, int *result);
+void frdmc_new_trig_(int *itrig, int *idef, int *result);
+void frdmc_new_wf_(int *iwf, int *result);
+void frdmc_new_usdef_(int *iuser, int *result);
+void frdmc_new_trdef_(int *itrig, int *result);
+void frdmc_new_ftdef_(int *ifit, int *result);
+void frdmc_del_gen_(int *itrack, int *result);
+void frdmc_del_user_(int *iuser, int *result);
+void frdmc_del_wf_(int *iwf, int *result);
+
+void frdmc_add_history_(char *history, int *result);
+void frdmc_add_hdcomment_(char *comment, int *result);
+void frdmc_add_evcomment_(char *comment, int *result);
+
+void frdmc_init_dummy_(void);
+void frdmc_new_farray_(void);
+void frdmc_new_fmevt_(void);
+void frdmc_new_hits_(void);
+
+int frdmc_return_eventpointer_(void);
+
+#if 1 /* OBSOLETE */
+void frdmc_get_trigs_(int *res, int *MxTrig, int *NTrigpar, int *Trig); 
+#endif
+
+
+/*** some interfaces to rdmc utility functions ****/
+int frdmc_track_closest_(double *dist, double xyz[3],
+                      double *x, double *y, double *z);
+int frdmc_get_leading_muon_(void);
+int frdmc_is_secondary_(void);
+int frdmc_is_point_like_(void);
+int frdmc_is_track_like_(void);
+
+void frdmc_amanda_spartid_(int *id, char *string);
+
+/*###########################################*/
+/*****OBSOLETE***************/
+/*###########################################*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RDMC_H */
diff --git a/RALICE/icepack/iceconvert/rdmc_WF.c b/RALICE/icepack/iceconvert/rdmc_WF.c
new file mode 100644 (file)
index 0000000..a7a63ae
--- /dev/null
@@ -0,0 +1,56 @@
+
+/******** implements functions for the WF structure *********/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "rdmc.h"
+
+
+void rdmc_init_WF(waveform *wf){
+  wf->id = wf->om = wf->ch = wf->pa = RDMC_NA ;
+  wf->ndigi   = 0;
+  wf->t_start = wf->t_bin = 0.;
+  wf->baseline =   RDMC_WF_BASELINE_NA ;
+  wf->digi=NULL;
+}
+
+void rdmc_clear_WF(waveform *wf){
+
+  rdmc_free_WF(wf);
+  rdmc_init_WF(wf);
+}
+
+
+void rdmc_free_WF(waveform *wf){
+
+  if (wf->digi !=NULL) free(wf->digi);
+    wf->ndigi=0;
+    wf->digi=NULL;
+}
+
+
+
+/****************************************************************************
+ * copies the waveform *in to *out by overwriting.
+ * If in == out, nothing is done.
+ ****************************************************************************/
+void rdmc_cp_WF(waveform *ou, waveform *in)
+{
+ if ((in == NULL) || (ou == NULL) || (in == ou))
+    return;
+
+  memcpy(ou, in, sizeof(waveform));
+
+  if (ou->ndigi > 0){
+
+    ou->digi = malloc(in->ndigi*sizeof(float));
+
+    if (!(ou->digi)){
+      ou->ndigi = 0;
+    } else {
+       memcpy(ou->digi, in->digi, in->ndigi*sizeof(float));
+    }
+  }
+
+} /* rdmc_cp_WF() */
diff --git a/RALICE/icepack/iceconvert/rdmc_array.c b/RALICE/icepack/iceconvert/rdmc_array.c
new file mode 100644 (file)
index 0000000..77e0417
--- /dev/null
@@ -0,0 +1,509 @@
+
+/*
+ *  functions for the array structure 
+ */
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rdmc.h"
+
+#include "amanda.h"
+#include "baikal.h"
+#include "dumand.h"
+#include "uwi.h"
+
+
+/****************************************************************************/
+/* The function rarr() reads the array info of a file                       */
+/****************************************************************************/
+
+int rdmc_rarr(mcfile *fp, array *ar)
+{
+  int r;
+  
+  switch(fp->format) {
+#ifdef DUMAND_ASCII_F
+  case DUMAND_ASCII_F:       /* if it is a dumand-like format */
+    r = rdmc_rarr_ascii(fp, ar)